From: Nick Clifton Date: Thu, 14 Sep 2000 01:47:38 +0000 (+0000) Subject: Add support for the MIPS32 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=156c2f8bf75a86dfa719220f9f259196d9d2491b;p=binutils-gdb.git Add support for the MIPS32 --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0a987a7384a..69d43f8b2a1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2000-09-13 Anders Norlander + + * cpu-mips.c (arch_info_struct): Add mips:4K + * bfd-in2.h (bfd_mach_mips4K): New define. + * archures.c: Add bfd_mach_mips4K to comment. + * elf32-mips.c (_bfd_mips_elf_final_write_processing): Return + E_MIPS_ARCH_2 for bfd_mach_mips4K. + Wed Sep 13 19:31:39 2000 Marco Franzen * som.c (som_write_symbol_strings): Do not used fixed buffers, diff --git a/bfd/archures.c b/bfd/archures.c index 3b68c320f41..70fa0868b2c 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -127,6 +127,7 @@ DESCRIPTION .#define bfd_mach_mips6000 6000 .#define bfd_mach_mips8000 8000 .#define bfd_mach_mips10000 10000 +.#define bfd_mach_mips4K 32 .#define bfd_mach_mips16 16 . bfd_arch_i386, {* Intel 386 *} .#define bfd_mach_i386_i386 0 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ca6e36b2ee7..fe3459f0772 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1394,6 +1394,7 @@ enum bfd_architecture #define bfd_mach_mips8000 8000 #define bfd_mach_mips10000 10000 #define bfd_mach_mips16 16 +#define bfd_mach_mips4K 32 bfd_arch_i386, /* Intel 386 */ #define bfd_mach_i386_i386 0 #define bfd_mach_i386_i8086 1 diff --git a/bfd/cpu-mips.c b/bfd/cpu-mips.c index c52fbecf54d..8090b7c54ea 100644 --- a/bfd/cpu-mips.c +++ b/bfd/cpu-mips.c @@ -53,6 +53,7 @@ I_mips5000, I_mips6000, I_mips8000, I_mips10000, +I_mips4K, I_mips16 }; @@ -75,8 +76,7 @@ static const bfd_arch_info_type arch_info_struct[] = N (32, 32, bfd_mach_mips6000, "mips:6000", false, NN(I_mips6000)), N (64, 64, bfd_mach_mips8000, "mips:8000", false, NN(I_mips8000)), N (64, 64, bfd_mach_mips10000, "mips:10000", false, NN(I_mips10000)), - - + N (32, 32, bfd_mach_mips4K, "mips:4K", false, NN(I_mips4K)), N (64, 64, bfd_mach_mips16, "mips:16", false, 0), }; diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 5ab839e06cd..fd8847a8e2c 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1848,6 +1848,9 @@ elf_mips_mach (flags) case E_MIPS_MACH_4650: return bfd_mach_mips4650; + case E_MIPS_MACH_MIPS32: + return bfd_mach_mips4K; + default: switch (flags & EF_MIPS_ARCH) { @@ -2347,6 +2350,10 @@ _bfd_mips_elf_final_write_processing (abfd, linker) case bfd_mach_mips8000: val = E_MIPS_ARCH_4; break; + + case bfd_mach_mips4K: + val = E_MIPS_ARCH_2 | E_MIPS_MACH_MIPS32; + break; } elf_elfheader (abfd)->e_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH); diff --git a/binutils/ChangeLog b/binutils/ChangeLog index d0399434cb0..4632f349374 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2000-09-13 Anders Norlander + + * readelf.c (get_machine_flags): Also print EF_MIPS_MACH field. + + * NEWS: Mention support for MIPS32. + 2000-09-08 Nick Clifton * MAINTAINERS: Add Stephane Carrez as maintainer for 68HC[11|12]. diff --git a/binutils/NEWS b/binutils/NEWS index 61555af986e..5ad5c8f04d3 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Support for the MIPS32, by Anders Norlander. + * Support for the i860, by Jason Eckhardt. * Support for CRIS (Axis Communications ETRAX series). diff --git a/binutils/readelf.c b/binutils/readelf.c index 4bb4cbd4360..d9686731fda 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1461,6 +1461,16 @@ get_machine_flags (e_flags, e_machine) if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4) strcat (buf, ", mips4"); + + switch ((e_flags & EF_MIPS_MACH)) + { + case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break; + case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break; + case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break; + case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break; + case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break; + case E_MIPS_MACH_MIPS32: strcat (buf, ", mips32"); break; + } break; case EM_SPARCV9: diff --git a/gas/ChangeLog b/gas/ChangeLog index 2d015b6007b..6b401dfebdc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,19 @@ +2000-09-13 Anders Norlander + + * config/tc-mips.c (md_begin): Recognize 4Kc, 4Km and 4Kp processors. + (md_parse_option): Ditto. + (md_longopts): Add -mips32 option. + (md_show_usage): Document new options. + (mips_ip): Assemble sdbbp 20 bit 'm' args for MIPS32. + (mips_ip): Assemble mfc0 with a sub-selection code. + (validate_mips_insn): Handle 'H' (OP_*_SEL) and 'm' (OP_*_CODE20). + (mips_cpu_to_str): New function. + (mips_ip): Use mips_cpu_to_str instead of printing numeric cpu value. + Use CPU_* defines instead of hardcoded numbers. + + * doc/as.texinfo: Document new options. + * doc/c-mips.texi: Ditto. + 2000-09-12 Kazu Hirata * as.h: Fix formatting. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index d76d1471fbc..416436a9e1d 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -263,19 +263,19 @@ static int mips_gp32 = 0; -- Jim Blandy */ -#define hilo_interlocks (mips_cpu == 4010 \ +#define hilo_interlocks (mips_cpu == CPU_R4010 \ ) /* 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_cpu == 3900) + || mips_cpu == CPU_R3900) /* As with other "interlocks" this is used by hardware that has FP (co-processor) interlocks. */ /* Itbl support may require additional care here. */ -#define cop_interlocks (mips_cpu == 4300 \ +#define cop_interlocks (mips_cpu == CPU_R4300 \ ) /* Is this a mfhi or mflo instruction? */ @@ -330,7 +330,7 @@ static int mips_any_noreorder; static int mips_7000_hilo_fix; /* The size of the small data section. */ -static int g_switch_value = 8; +static unsigned int g_switch_value = 8; /* Whether the -G option was used. */ static int g_switch_seen = 0; @@ -507,7 +507,7 @@ static const int mips32_to_16_reg_map[] = /* Map mips16 register numbers to normal MIPS register numbers. */ -static const int mips16_to_32_reg_map[] = +static const unsigned int mips16_to_32_reg_map[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; @@ -641,7 +641,7 @@ enum mips_regclass { MIPS_GR_REG, MIPS_FP_REG, MIPS16_REG }; static int insn_uses_reg PARAMS ((struct mips_cl_insn *ip, unsigned int reg, enum mips_regclass class)); -static int reg_needs_delay PARAMS ((int)); +static int reg_needs_delay PARAMS ((unsigned int)); static void mips16_mark_labels PARAMS ((void)); static void append_insn PARAMS ((char *place, struct mips_cl_insn * ip, @@ -705,6 +705,7 @@ 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 int validate_mips_insn PARAMS ((const struct mips_opcode *)); @@ -850,16 +851,44 @@ static boolean mips16_small, mips16_ext; static segT pdr_seg; #endif -/* - * This function is called once, at assembler startup time. It should - * set up all the tables, etc. that the MD part of the assembler will need. - */ +static char * +mips_cpu_to_str (cpu) + int cpu; +{ + 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; + } +} + +/* This function is called once, at assembler startup time. It should + set up all the tables, etc. that the MD part of the assembler will need. */ + void md_begin () { boolean ok = false; register const char *retval = NULL; - register unsigned int i = 0; + int i = 0; const char *cpu; char *a = NULL; int broken = 0; @@ -892,95 +921,100 @@ md_begin () if (strcmp (cpu, "mips") == 0) { if (mips_opts.isa < 0) - mips_cpu = 3000; + mips_cpu = CPU_R3000; else if (mips_opts.isa == 2) - mips_cpu = 6000; + mips_cpu = CPU_R6000; else if (mips_opts.isa == 3) - mips_cpu = 4000; + mips_cpu = CPU_R4000; else if (mips_opts.isa == 4) - mips_cpu = 8000; + mips_cpu = CPU_R8000; else - mips_cpu = 3000; + mips_cpu = CPU_R3000; } else if (strcmp (cpu, "r3900") == 0 || strcmp (cpu, "mipstx39") == 0 ) - mips_cpu = 3900; + mips_cpu = CPU_R3900; else if (strcmp (cpu, "r6000") == 0 || strcmp (cpu, "mips2") == 0) - mips_cpu = 6000; + mips_cpu = CPU_R6000; else if (strcmp (cpu, "mips64") == 0 || strcmp (cpu, "r4000") == 0 || strcmp (cpu, "mips3") == 0) - mips_cpu = 4000; + mips_cpu = CPU_R4000; else if (strcmp (cpu, "r4400") == 0) - mips_cpu = 4400; + mips_cpu = CPU_R4400; else if (strcmp (cpu, "mips64orion") == 0 || strcmp (cpu, "r4600") == 0) - mips_cpu = 4600; + mips_cpu = CPU_R4600; else if (strcmp (cpu, "r4650") == 0) - mips_cpu = 4650; + mips_cpu = CPU_R4650; else if (strcmp (cpu, "mips64vr4300") == 0) - mips_cpu = 4300; + mips_cpu = CPU_R4300; else if (strcmp (cpu, "mips64vr4111") == 0) - mips_cpu = 4111; + mips_cpu = CPU_R4111; else if (strcmp (cpu, "mips64vr4100") == 0) - mips_cpu = 4100; + mips_cpu = CPU_VR4100; else if (strcmp (cpu, "r4010") == 0) - mips_cpu = 4010; + 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 = 5000; + mips_cpu = CPU_R5000; else if (strcmp (cpu, "r8000") == 0 || strcmp (cpu, "mips4") == 0) - mips_cpu = 8000; + mips_cpu = CPU_R8000; else if (strcmp (cpu, "r10000") == 0) - mips_cpu = 10000; + mips_cpu = CPU_R10000; else if (strcmp (cpu, "mips16") == 0) mips_cpu = 0; /* FIXME */ else - mips_cpu = 3000; + mips_cpu = CPU_R3000; } - if (mips_cpu == 3000 - || mips_cpu == 3900) + if (mips_cpu == CPU_R3000 + || mips_cpu == CPU_R3900) mips_isa_from_cpu = 1; - else if (mips_cpu == 6000 - || mips_cpu == 4010) + else if (mips_cpu == CPU_R6000 + || mips_cpu == CPU_R4010) mips_isa_from_cpu = 2; - else if (mips_cpu == 4000 - || mips_cpu == 4100 - || mips_cpu == 4111 - || mips_cpu == 4400 - || mips_cpu == 4300 - || mips_cpu == 4600 - || mips_cpu == 4650) + 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 == 5000 - || mips_cpu == 8000 - || mips_cpu == 10000) + else if (mips_cpu == CPU_R5000 + || mips_cpu == CPU_R8000 + || mips_cpu == CPU_R10000) mips_isa_from_cpu = 4; else @@ -1007,8 +1041,8 @@ md_begin () cpu = NULL; if (a != NULL) { - free (a); - a = NULL; + free (a); + a = NULL; } if (mips_opts.isa == 1 && mips_trap) @@ -1038,16 +1072,16 @@ md_begin () switch (mips_opts.isa) { case 1: - ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 3000); + ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R3000); break; case 2: - ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 6000); + ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R6000); break; case 3: - ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 4000); + ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R4000); break; case 4: - ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 8000); + ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R8000); break; } } @@ -1382,7 +1416,7 @@ insn_uses_reg (ip, reg, class) static int reg_needs_delay (reg) - int reg; + unsigned int reg; { unsigned long prev_pinfo; @@ -1625,7 +1659,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) though the tx39's divide insns still do require the delay. */ if (! (hilo_interlocks - || (mips_cpu == 3900 && (pinfo & INSN_MULT))) + || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT))) && (mips_optimize == 0 || (pinfo & INSN_WRITE_LO))) nops += 2; @@ -1647,7 +1681,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) insert a NOP. Some newer processors have interlocks. Also the note tx39's multiply above. */ if (! (hilo_interlocks - || (mips_cpu == 3900 && (pinfo & INSN_MULT))) + || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT))) && (mips_optimize == 0 || (pinfo & INSN_WRITE_HI))) nops += 2; @@ -1686,11 +1720,11 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO) && (pinfo & INSN_WRITE_LO) && ! (hilo_interlocks - || (mips_cpu == 3900 && (pinfo & INSN_MULT)))) + || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT)))) || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI) && (pinfo & INSN_WRITE_HI) && ! (hilo_interlocks - || (mips_cpu == 3900 && (pinfo & INSN_MULT))))) + || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT))))) prev_prev_nop = 1; else prev_prev_nop = 0; @@ -1707,7 +1741,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) to 0. */ if (nops > 0 && ! mips_opts.noreorder - && ip->insn_opcode == (mips_opts.mips16 ? 0x6500 : 0)) + && ip->insn_opcode == (unsigned) (mips_opts.mips16 ? 0x6500 : 0)) --nops; /* Now emit the right number of NOP instructions. */ @@ -2040,7 +2074,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) | INSN_COPROC_MOVE_DELAY | INSN_WRITE_COND_CODE))) || (! (hilo_interlocks - || (mips_cpu == 3900 && (pinfo & INSN_MULT))) + || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT))) && (prev_pinfo & (INSN_READ_LO | INSN_READ_HI))) @@ -2524,7 +2558,7 @@ macro_build (place, counter, ep, name, fmt, va_alist) && insn.insn_mo->pinfo != INSN_MACRO && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu, mips_gp32) - && (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0)) + && (mips_cpu != CPU_R4650 || (insn.insn_mo->pinfo & FP_D) == 0)) break; ++insn.insn_mo; @@ -4839,7 +4873,7 @@ macro (ip) lr = 1; goto ld; case M_LDC1_AB: - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -4928,7 +4962,7 @@ macro (ip) s = "scd"; goto st; case M_SDC1_AB: - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -5416,7 +5450,7 @@ macro (ip) } case M_L_DOB: - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -5457,7 +5491,7 @@ macro (ip) * But, the resulting address is the same after relocation so why * generate the extra instruction? */ - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -5475,7 +5509,7 @@ macro (ip) goto ldd_std; case M_S_DAB: - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -6104,7 +6138,7 @@ macro2 (ip) break; case M_S_DOB: - if (mips_cpu == 4650) + if (mips_cpu == CPU_R4650) { as_bad (_("opcode not supported on this processor")); return; @@ -6947,6 +6981,7 @@ validate_mips_insn (opc) case 'E': USE_BITS (OP_MASK_RT, OP_SH_RT); break; case 'F': break; case 'G': USE_BITS (OP_MASK_RD, OP_SH_RD); break; + case 'H': USE_BITS (OP_MASK_SEL, OP_SH_SEL); break; case 'I': break; case 'L': break; case 'M': USE_BITS (OP_MASK_CCC, OP_SH_CCC); break; @@ -6966,6 +7001,7 @@ validate_mips_insn (opc) case 'j': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break; case 'k': USE_BITS (OP_MASK_CACHE, OP_SH_CACHE); break; case 'l': break; + case 'm': USE_BITS (OP_MASK_CODE20, OP_SH_CODE20); break; case 'o': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break; case 'p': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break; case 'q': USE_BITS (OP_MASK_CODE2, OP_SH_CODE2); break; @@ -7078,7 +7114,7 @@ mips_ip (str, ip) if (insn->pinfo != INSN_MACRO) { - if (mips_cpu == 4650 && (insn->pinfo & FP_D) != 0) + if (mips_cpu == CPU_R4650 && (insn->pinfo & FP_D) != 0) ok = false; } @@ -7094,8 +7130,8 @@ mips_ip (str, ip) { static char buf[100]; sprintf (buf, - _("opcode not supported on this processor: %d (MIPS%d)"), - mips_cpu, mips_opts.isa); + _("opcode not supported on this processor: %s (MIPS%d)"), + mips_cpu_to_str (mips_cpu), mips_opts.isa); insn_error = buf; return; @@ -7231,6 +7267,24 @@ mips_ip (str, ip) s = expr_end; continue; + case 'm': /* Full 20 bit break code. */ + my_getExpression (&imm_expr, s); + + check_absolute_expr (ip, &imm_expr); + + if ((unsigned) imm_expr.X_add_number > 0xfffff) + { + as_warn (_("Illegal break code (%ld)"), + (long) imm_expr.X_add_number); + imm_expr.X_add_number &= 0xfffff; + } + + ip->insn_opcode |= imm_expr.X_add_number << 6; + imm_expr.X_op = O_absent; + s = expr_end; + + continue; + case 'B': /* syscall code */ my_getExpression (&imm_expr, s); check_absolute_expr (ip, &imm_expr); @@ -7584,7 +7638,7 @@ mips_ip (str, ip) length = f64 ? 8 : 4; } - assert (length == (f64 ? 8 : 4)); + assert (length == (unsigned) (f64 ? 8 : 4)); if (*args == 'f' || (*args == 'l' @@ -7894,6 +7948,28 @@ mips_ip (str, ip) ip->insn_opcode |= regno << OP_SH_CCC; continue; + case 'H': + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) + s += 2; + if (isdigit ((unsigned char) *s)) + { + c = 0; + do + { + c *= 10; + c += *s - '0'; + ++s; + } + while (isdigit ((unsigned char) *s)); + } + else + c = 8; /* Invalid sel value. */ + + if (c > 7) + as_bad (_("invalid coprocessor sub-selection value (0-7)")); + ip->insn_opcode |= c; + continue; + default: as_bad (_("bad char = '%c'\n"), *args); internalError (); @@ -8813,7 +8889,8 @@ md_number_to_chars (buf, val, n) CONST char *md_shortopts = "O::g::G:"; -struct option md_longopts[] = { +struct option md_longopts[] = +{ #define OPTION_MIPS1 (OPTION_MD_BASE + 1) {"mips0", no_argument, NULL, OPTION_MIPS1}, {"mips1", no_argument, NULL, OPTION_MIPS1}, @@ -8827,78 +8904,73 @@ struct option md_longopts[] = { {"mcpu", required_argument, NULL, OPTION_MCPU}, #define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 6) {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC}, - -#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7) -#define OPTION_NON_SHARED (OPTION_MD_BASE + 8) - -#define OPTION_TRAP (OPTION_MD_BASE + 9) +#define OPTION_TRAP (OPTION_MD_BASE + 7) {"trap", no_argument, NULL, OPTION_TRAP}, {"no-break", no_argument, NULL, OPTION_TRAP}, -#define OPTION_BREAK (OPTION_MD_BASE + 10) +#define OPTION_BREAK (OPTION_MD_BASE + 8) {"break", no_argument, NULL, OPTION_BREAK}, {"no-trap", no_argument, NULL, OPTION_BREAK}, -#define OPTION_EB (OPTION_MD_BASE + 11) +#define OPTION_EB (OPTION_MD_BASE + 9) {"EB", no_argument, NULL, OPTION_EB}, -#define OPTION_EL (OPTION_MD_BASE + 12) +#define OPTION_EL (OPTION_MD_BASE + 10) {"EL", no_argument, NULL, OPTION_EL}, -#define OPTION_M4650 (OPTION_MD_BASE + 13) +#define OPTION_M4650 (OPTION_MD_BASE + 11) {"m4650", no_argument, NULL, OPTION_M4650}, -#define OPTION_NO_M4650 (OPTION_MD_BASE + 14) +#define OPTION_NO_M4650 (OPTION_MD_BASE + 12) {"no-m4650", no_argument, NULL, OPTION_NO_M4650}, -#define OPTION_M4010 (OPTION_MD_BASE + 15) +#define OPTION_M4010 (OPTION_MD_BASE + 13) {"m4010", no_argument, NULL, OPTION_M4010}, -#define OPTION_NO_M4010 (OPTION_MD_BASE + 16) +#define OPTION_NO_M4010 (OPTION_MD_BASE + 14) {"no-m4010", no_argument, NULL, OPTION_NO_M4010}, -#define OPTION_M4100 (OPTION_MD_BASE + 17) +#define OPTION_M4100 (OPTION_MD_BASE + 15) {"m4100", no_argument, NULL, OPTION_M4100}, -#define OPTION_NO_M4100 (OPTION_MD_BASE + 18) +#define OPTION_NO_M4100 (OPTION_MD_BASE + 16) {"no-m4100", no_argument, NULL, OPTION_NO_M4100}, - -#define OPTION_XGOT (OPTION_MD_BASE + 19) -#define OPTION_32 (OPTION_MD_BASE + 20) -#define OPTION_64 (OPTION_MD_BASE + 21) - -#define OPTION_MIPS16 (OPTION_MD_BASE + 22) +#define OPTION_MIPS16 (OPTION_MD_BASE + 17) {"mips16", no_argument, NULL, OPTION_MIPS16}, -#define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23) +#define OPTION_NO_MIPS16 (OPTION_MD_BASE + 18) {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16}, - -#define OPTION_M3900 (OPTION_MD_BASE + 26) +#define OPTION_M3900 (OPTION_MD_BASE + 19) {"m3900", no_argument, NULL, OPTION_M3900}, -#define OPTION_NO_M3900 (OPTION_MD_BASE + 27) +#define OPTION_NO_M3900 (OPTION_MD_BASE + 20) {"no-m3900", no_argument, NULL, OPTION_NO_M3900}, - -#define OPTION_MABI (OPTION_MD_BASE + 38) +#define OPTION_MABI (OPTION_MD_BASE + 21) {"mabi", required_argument, NULL, OPTION_MABI}, - -#define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 39) +#define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 22) {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX}, -#define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40) +#define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 23) {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX}, - -#ifdef OBJ_ELF - {"KPIC", no_argument, NULL, OPTION_CALL_SHARED}, - {"xgot", no_argument, NULL, OPTION_XGOT}, - {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, - {"non_shared", no_argument, NULL, OPTION_NON_SHARED}, - {"32", no_argument, NULL, OPTION_32}, - {"64", no_argument, NULL, OPTION_64}, -#endif - -#define OPTION_GP32 (OPTION_MD_BASE + 41) -#define OPTION_GP64 (OPTION_MD_BASE + 42) +#define OPTION_GP32 (OPTION_MD_BASE + 24) {"mgp32", no_argument, NULL, OPTION_GP32}, +#define OPTION_GP64 (OPTION_MD_BASE + 25) {"mgp64", no_argument, NULL, OPTION_GP64}, - -#define OPTION_CONSTRUCT_FLOATS (OPTION_MD_BASE + 43) +#define OPTION_CONSTRUCT_FLOATS (OPTION_MD_BASE + 26) {"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS}, - -#define OPTION_NO_CONSTRUCT_FLOATS (OPTION_MD_BASE + 44) +#define OPTION_NO_CONSTRUCT_FLOATS (OPTION_MD_BASE + 27) {"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) +#define OPTION_NON_SHARED (OPTION_ELF_BASE + 1) +#define OPTION_XGOT (OPTION_ELF_BASE + 2) +#define OPTION_32 (OPTION_ELF_BASE + 3) +#define OPTION_64 (OPTION_ELF_BASE + 4) + {"KPIC", no_argument, NULL, OPTION_CALL_SHARED}, + {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, + {"non_shared", no_argument, NULL, OPTION_NON_SHARED}, + {"xgot", no_argument, NULL, OPTION_XGOT}, + {"32", no_argument, NULL, OPTION_32}, + {"64", no_argument, NULL, OPTION_64}, +#endif {NULL, no_argument, NULL, 0} }; -size_t md_longopts_size = sizeof(md_longopts); +size_t md_longopts_size = sizeof (md_longopts); int md_parse_option (c, arg) @@ -8997,70 +9069,74 @@ md_parse_option (c, arg) if (strcmp (p, "10000") == 0 || strcmp (p, "10k") == 0 || strcmp (p, "10K") == 0) - mips_cpu = 10000; + mips_cpu = CPU_R10000; break; case '2': if (strcmp (p, "2000") == 0 || strcmp (p, "2k") == 0 || strcmp (p, "2K") == 0) - mips_cpu = 2000; + mips_cpu = CPU_R2000; break; case '3': if (strcmp (p, "3000") == 0 || strcmp (p, "3k") == 0 || strcmp (p, "3K") == 0) - mips_cpu = 3000; + mips_cpu = CPU_R3000; else if (strcmp (p, "3900") == 0) - mips_cpu = 3900; + mips_cpu = CPU_R3900; break; case '4': if (strcmp (p, "4000") == 0 || strcmp (p, "4k") == 0 || strcmp (p, "4K") == 0) - mips_cpu = 4000; + mips_cpu = CPU_R4000; else if (strcmp (p, "4100") == 0) - mips_cpu = 4100; + mips_cpu = CPU_VR4100; else if (strcmp (p, "4111") == 0) - mips_cpu = 4111; + mips_cpu = CPU_R4111; else if (strcmp (p, "4300") == 0) - mips_cpu = 4300; + mips_cpu = CPU_R4300; else if (strcmp (p, "4400") == 0) - mips_cpu = 4400; + mips_cpu = CPU_R4400; else if (strcmp (p, "4600") == 0) - mips_cpu = 4600; + mips_cpu = CPU_R4600; else if (strcmp (p, "4650") == 0) - mips_cpu = 4650; + mips_cpu = CPU_R4650; else if (strcmp (p, "4010") == 0) - mips_cpu = 4010; + 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 = 5000; + mips_cpu = CPU_R5000; break; case '6': if (strcmp (p, "6000") == 0 || strcmp (p, "6k") == 0 || strcmp (p, "6K") == 0) - mips_cpu = 6000; + mips_cpu = CPU_R6000; break; case '8': if (strcmp (p, "8000") == 0 || strcmp (p, "8k") == 0 || strcmp (p, "8K") == 0) - mips_cpu = 8000; + mips_cpu = CPU_R8000; break; case 'o': if (strcmp (p, "orion") == 0) - mips_cpu = 4600; + mips_cpu = CPU_R4600; break; case 'm': @@ -9073,7 +9149,7 @@ md_parse_option (c, arg) case 5261: case 5721: case 7000: - mips_cpu = 5000; + mips_cpu = CPU_R5000; break; default: break; @@ -9081,10 +9157,10 @@ md_parse_option (c, arg) } if (sv - && (mips_cpu != 4300 - && mips_cpu != 4100 - && mips_cpu != 4111 - && mips_cpu != 5000)) + && (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; @@ -9100,28 +9176,35 @@ md_parse_option (c, arg) break; case OPTION_M4650: - mips_cpu = 4650; + mips_cpu = CPU_R4650; break; case OPTION_NO_M4650: break; case OPTION_M4010: - mips_cpu = 4010; + mips_cpu = CPU_R4010; break; case OPTION_NO_M4010: break; case OPTION_M4100: - mips_cpu = 4100; + mips_cpu = CPU_VR4100; break; case OPTION_NO_M4100: break; + case OPTION_MIPS32: + mips_cpu = CPU_MIPS32; + break; + + case OPTION_NO_MIPS32: + break; + case OPTION_M3900: - mips_cpu = 3900; + mips_cpu = CPU_R3900; break; case OPTION_NO_M3900: @@ -9333,6 +9416,9 @@ 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); fputc ('\n', stream); fprintf (stream, _("\ @@ -9348,6 +9434,9 @@ 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")); diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index f2f434cd2b2..110d23a439d 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -278,7 +278,7 @@ Here is a brief summary of how to invoke @code{@value{AS}}. For details, @end ifset @ifset MIPS [ -nocpp ] [ -EL ] [ -EB ] [ -G @var{num} ] [ -mcpu=@var{CPU} ] - [ -mips1 ] [ -mips2 ] [ -mips3 ] [ -m4650 ] [ -no-m4650 ] + [ -mips1 ] [ -mips2 ] [ -mips3 ] [ -m4650 ] [ -no-m4650 ] [ -mips32 ] [ -no-mips32 ] [ --trap ] [ --break ] [ --emulation=@var{name} ] @end ifset @@ -679,6 +679,12 @@ the @samp{mad} and @samp{madu} instruction, and to not schedule @samp{nop} instructions around accesses to the @samp{HI} and @samp{LO} registers. @samp{-no-m4650} turns off this option. +@item -mips32 +@itemx -no-mips32 +Generate code for the @sc{MIPS32} architecture. This tells the assembler to +accept ISA level 2 instructions and MIPS32 extensions including some @sc{r4000} +instructions. + @item -mcpu=@var{CPU} Generate code for a particular MIPS cpu. This has little effect on the assembler, but it is passed by @code{@value{GCC}}. diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi index 792b847a7ee..137dfe99b18 100644 --- a/gas/doc/c-mips.texi +++ b/gas/doc/c-mips.texi @@ -141,6 +141,9 @@ rm5721, rm7000, 8000, 10000 +4Kc +4Km +4Kp @end quotation diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 67f3dd44814..1256f71f4c2 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2000-09-13 Anders Norlander + + * mips.h (E_MIPS_MACH_4K): New define. + 2000-09-05 Alan Modra * hppa.h: Fix a comment. diff --git a/include/elf/mips.h b/include/elf/mips.h index 14ad20f7378..18185e7dfe6 100644 --- a/include/elf/mips.h +++ b/include/elf/mips.h @@ -153,7 +153,9 @@ END_RELOC_NUMBERS (R_MIPS_maxext) #define E_MIPS_MACH_4100 0x00830000 #define E_MIPS_MACH_4650 0x00850000 #define E_MIPS_MACH_4111 0x00880000 - +/* -mips32 code. + It is easier to treat MIPS32 as a machine rather than an architecture. */ +#define E_MIPS_MACH_MIPS32 0x00890000 /* Processor specific section indices. These sections do not actually exist. Symbols with a st_shndx field corresponding to one of these diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index ac84ae2a938..73b4dee0426 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,20 @@ +2000-09-13 Anders Norlander + + * mips.h: Use defines instead of hard-coded processor numbers. + (CPU_R2000, CPU_R3000, CPU_R3900, CPU_R4000, CPU_R4010, + CPU_VR4100, CPU_R4111, CPU_R4300, CPU_R4400, CPU_R4600, CPU_R4650, + CPU_R5000, CPU_R6000, CPU_R8000, CPU_R10000, CPU_MIPS32, CPU_4K, + CPU_4KC, CPU_4KM, CPU_4KP): Define.. + (OPCODE_IS_MEMBER): Use new defines. + (OP_MASK_SEL, OP_SH_SEL): Define. + (OP_MASK_CODE20, OP_SH_CODE20): Define. + Add 'P' to used characters. + Use 'H' for coprocessor select field. + Use 'm' for 20 bit breakpoint code. + Document new arg characters and add to used characters. + (INSN_MIPS32): New define for MIPS32 extensions. + (OPCODE_IS_MEMBER): Recognize MIPS32 instructions. + 2000-09-05 Alan Modra * hppa.h: Mention cz completer. diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 68fe57a8aae..95415e0c30e 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -126,6 +126,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #define OP_MASK_MMISUB 0x1f #define OP_MASK_PERFREG 0x1f /* Performance monitoring */ #define OP_SH_PERFREG 1 +#define OP_SH_SEL 0 /* Coprocessor select field */ +#define OP_MASK_SEL 0x7 /* The sel field of mfcZ and mtcZ. */ +#define OP_SH_CODE20 6 /* 20 bit breakpoint code */ +#define OP_MASK_CODE20 0xfffff /* This structure holds information for a particular instruction. */ @@ -172,6 +176,7 @@ struct mips_opcode "i" 16 bit unsigned immediate (OP_*_IMMEDIATE) "j" 16 bit signed immediate (OP_*_DELTA) "k" 5 bit cache opcode in target register position (OP_*_CACHE) + "m" 20 bit breakpoint code (OP_*_CODE20) "o" 16 bit signed offset (OP_*_DELTA) "p" 16 bit PC relative branch target address (OP_*_DELTA) "q" 10 bit extra breakpoint code (OP_*_CODE2) @@ -200,6 +205,7 @@ struct mips_opcode "E" 5 bit target register (OP_*_RT) "G" 5 bit destination register (OP_*_RD) "P" 5 bit performance-monitor register (OP_*_PERFREG) + "H" 3 bit sel field (OP_*_SEL) Macro instructions: "A" General 32 bit expression @@ -215,8 +221,8 @@ struct mips_opcode Characters used so far, for quick reference when adding more: "<>()," - "ABCDEFGILMNSTRVW" - "abcdfhijklopqrstuvwxz" + "ABCDEFGHILMNPSTRVW" + "abcdfhijklmopqrstuvwxz" */ /* These are the bits which may be set in the pinfo field of an @@ -319,10 +325,32 @@ struct mips_opcode #define INSN_4100 0x00000040 /* Toshiba R3900 instruction. */ #define INSN_3900 0x00000080 - +/* MIPS32 instruction (4Kc, 4Km, 4Kp). */ +#define INSN_MIPS32 0x00000100 /* 32-bit code running on a ISA3+ CPU. */ #define INSN_GP32 0x00001000 +/* CPU defines, use instead of hardcoding processor number. Keep this + in sync with bfd/archures.c in order for machine selection to work. */ +#define CPU_R2000 2000 +#define CPU_R3000 3000 +#define CPU_R3900 3900 +#define CPU_R4000 4000 +#define CPU_R4010 4010 +#define CPU_VR4100 4100 +#define CPU_R4111 4111 +#define CPU_R4300 4300 +#define CPU_R4400 4400 +#define CPU_R4600 4600 +#define CPU_R4650 4650 +#define CPU_R5000 5000 +#define CPU_R6000 6000 +#define CPU_R8000 8000 +#define CPU_R10000 10000 +#define CPU_MIPS16 16 +#define CPU_MIPS32 32 +#define CPU_4K CPU_MIPS32 + /* Test for membership in an ISA including chip specific ISAs. INSN is pointer to an element of the opcode table; ISA is the specified ISA to test against; and CPU is the CPU specific ISA @@ -331,20 +359,16 @@ struct mips_opcode a machine with 64-bit registers; see the documentation under -mgp32 in the MIPS gas docs. */ -#define OPCODE_IS_MEMBER(insn,isa,cpu,gp32) \ - ((((insn)->membership & INSN_ISA) != 0 \ - && ((insn)->membership & INSN_ISA) <= isa \ - && ((insn)->membership & INSN_GP32 ? gp32 : 1)) \ - || (cpu == 4650 \ - && ((insn)->membership & INSN_4650) != 0) \ - || (cpu == 4010 \ - && ((insn)->membership & INSN_4010) != 0) \ - || ((cpu == 4100 \ - || cpu == 4111 \ - ) \ - && ((insn)->membership & INSN_4100) != 0) \ - || (cpu == 3900 \ - && ((insn)->membership & INSN_3900) != 0)) +#define OPCODE_IS_MEMBER(insn, isa, cpu, gp32) \ + ((((insn)->membership & INSN_ISA) != 0 \ + && ((insn)->membership & INSN_ISA) <= (unsigned) isa \ + && ((insn)->membership & INSN_GP32 ? gp32 : 1)) \ + || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0) \ + || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0) \ + || ((cpu == CPU_VR4100 || cpu == CPU_R4111) \ + && ((insn)->membership & INSN_4100) != 0) \ + || (cpu == CPU_MIPS32 && ((insn)->membership & INSN_MIPS32) != 0) \ + || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)) /* This is a list of macro expanded instructions. * diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 31a00765f93..69868d00d79 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,19 @@ +2000-09-13 Anders Norlander + + * mips-opc.c (mips_builtin_opcodes): Support cache instruction on 4K cores. + Add mfc0 and mtc0 with sub-selection values. + Add clo and clz opcodes. + Add msub and msubu instructions for MIPS32. + Add madd/maddu aliases for mad/madu for MIPS32. + Support wait, deret, eret, movn, pref for MIPS32. + Support tlbp, tlbr, tlbwi, tlbwr. + (P4): New define. + + * mips-dis.c (print_insn_arg): Print sdbbp 'm' args. + (print_insn_arg): Handle 'H' args. + (set_mips_isa_type): Recognize 4K. + Use CPU_* defines instead of hardcoded numbers. + 2000-09-11 Catherine Moore * d30v-opc.c (d30v_operand_t): New operand type Rb2. diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index fa33821f32c..4c76cde4aae 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -177,6 +177,11 @@ print_insn_arg (d, l, pc, info) (l >> OP_SH_CODE2) & OP_MASK_CODE2); break; + case 'm': + (*info->fprintf_func) (info->stream, "0x%x", + (l >> OP_SH_CODE20) & OP_MASK_CODE20); + break; + case 'C': (*info->fprintf_func) (info->stream, "0x%x", (l >> OP_SH_COPZ) & OP_MASK_COPZ); @@ -235,6 +240,10 @@ print_insn_arg (d, l, pc, info) (l >> OP_SH_PERFREG) & OP_MASK_PERFREG); break; + case 'H': + (*info->fprintf_func) (info->stream, "%d", + (l >> OP_SH_SEL) & OP_MASK_SEL); + break; default: /* xgettext:c-format */ @@ -264,71 +273,74 @@ set_mips_isa_type (mach, isa, cputype) switch (mach) { - case bfd_mach_mips3000: - target_processor = 3000; - mips_isa = 1; - break; - case bfd_mach_mips3900: - target_processor = 3900; - mips_isa = 1; - break; - case bfd_mach_mips4000: - target_processor = 4000; - mips_isa = 3; - break; - case bfd_mach_mips4010: - target_processor = 4010; - mips_isa = 2; - break; - case bfd_mach_mips4100: - target_processor = 4100; - mips_isa = 3; - break; - case bfd_mach_mips4111: - target_processor = 4100; - mips_isa = 3; - break; - case bfd_mach_mips4300: - target_processor = 4300; - mips_isa = 3; - break; - case bfd_mach_mips4400: - target_processor = 4400; - mips_isa = 3; - break; - case bfd_mach_mips4600: - target_processor = 4600; - mips_isa = 3; - break; - case bfd_mach_mips4650: - target_processor = 4650; - mips_isa = 3; - break; - case bfd_mach_mips5000: - target_processor = 5000; - mips_isa = 4; - break; - case bfd_mach_mips6000: - target_processor = 6000; - mips_isa = 2; - break; - case bfd_mach_mips8000: - target_processor = 8000; - mips_isa = 4; - break; - case bfd_mach_mips10000: - target_processor = 10000; - mips_isa = 4; - break; - case bfd_mach_mips16: - target_processor = 16; - mips_isa = 3; - break; - default: - target_processor = 3000; - mips_isa = 3; - break; - + case bfd_mach_mips3000: + target_processor = CPU_R3000; + mips_isa = 1; + break; + case bfd_mach_mips3900: + target_processor = CPU_R3900; + mips_isa = 1; + break; + case bfd_mach_mips4000: + target_processor = CPU_R4000; + mips_isa = 3; + break; + case bfd_mach_mips4010: + target_processor = CPU_R4010; + mips_isa = 2; + break; + case bfd_mach_mips4100: + target_processor = CPU_VR4100; + mips_isa = 3; + break; + case bfd_mach_mips4111: + target_processor = CPU_VR4100; /* FIXME: Shouldn't this be CPU_R4111 ??? */ + mips_isa = 3; + break; + case bfd_mach_mips4300: + target_processor = CPU_R4300; + mips_isa = 3; + break; + case bfd_mach_mips4400: + target_processor = CPU_R4400; + mips_isa = 3; + break; + case bfd_mach_mips4600: + target_processor = CPU_R4600; + mips_isa = 3; + break; + case bfd_mach_mips4650: + target_processor = CPU_R4650; + mips_isa = 3; + break; + case bfd_mach_mips4K: + target_processor = CPU_4K; + mips_isa = 2; + break; + case bfd_mach_mips5000: + target_processor = CPU_R5000; + mips_isa = 4; + break; + case bfd_mach_mips6000: + target_processor = CPU_R6000; + mips_isa = 2; + break; + case bfd_mach_mips8000: + target_processor = CPU_R8000; + mips_isa = 4; + break; + case bfd_mach_mips10000: + target_processor = CPU_R10000; + mips_isa = 4; + break; + case bfd_mach_mips16: + target_processor = CPU_MIPS16; + mips_isa = 3; + break; + default: + target_processor = CPU_R3000; + mips_isa = 3; + break; } *isa = mips_isa; diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c index 40f7ad6ef15..ca4208947ab 100644 --- a/opcodes/mips-opc.c +++ b/opcodes/mips-opc.c @@ -78,6 +78,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #define I4 INSN_ISA4 #define I5 INSN_ISA5 #define P3 INSN_4650 +#define P4 INSN_MIPS32 #define L1 INSN_4010 #define V1 INSN_4100 #define T3 INSN_3900 @@ -317,7 +318,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"c.ngt.s", "M,S,T", 0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4|M1 }, {"c.ngt.ps","S,T", 0x46c0003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I5 }, {"c.ngt.ps","M,S,T", 0x46c0003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I5 }, -{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, I3|T3|M1 }, +{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, I3|T3|M1|P4 }, {"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, I3 }, {"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S, I3 }, {"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_D, I2 }, @@ -327,6 +328,8 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, I1 }, {"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, I1 }, {"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, I1 }, +{"clo", "d,s", 0x70000021, 0xfc1f07ff, WR_d|RD_s, P4 }, +{"clz", "d,s", 0x70000020, 0xfc1f07ff, WR_d|RD_s, P4 }, {"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, I1 }, {"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, I1 }, {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, I1 }, @@ -355,7 +358,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { /* dctr and dctw are used on the r5000. */ {"dctr", "o(b)", 0xbc050000, 0xfc1f0000, RD_b, I3 }, {"dctw", "o(b)", 0xbc090000, 0xfc1f0000, RD_b, I3 }, -{"deret", "", 0x4200001f, 0xffffffff, 0, G2|M1 }, +{"deret", "", 0x4200001f, 0xffffffff, 0, G2|M1|P4 }, /* For ddiv, see the comments about div. */ {"ddiv", "z,s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3 }, {"ddiv", "d,v,t", 0, (int) M_DDIV_3, INSN_MACRO, I3 }, @@ -427,7 +430,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"dsub", "d,v,I", 0, (int) M_DSUB_I, INSN_MACRO, I3 }, {"dsubu", "d,v,t", 0x0000002f, 0xfc0007ff, WR_d|RD_s|RD_t, I3 }, {"dsubu", "d,v,I", 0, (int) M_DSUBU_I, INSN_MACRO, I3 }, -{"eret", "", 0x42000018, 0xffffffff, 0, I3|M1 }, +{"eret", "", 0x42000018, 0xffffffff, 0, I3|M1|P4 }, {"floor.l.d", "D,S", 0x4620000b, 0xffff003f, WR_D|RD_S|FP_D, I3 }, {"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S, I3 }, {"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_D, I2 }, @@ -524,19 +527,22 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"lwu", "t,o(b)", 0x9c000000, 0xfc000000, LDD|RD_b|WR_t, I3 }, {"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, I3 }, {"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b, I4 }, -{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3 }, -{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3 }, +{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3|P4 }, +{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3|P4 }, {"madd.d", "D,R,S,T", 0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4 }, {"madd.s", "D,R,S,T", 0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 }, {"madd.ps", "D,R,S,T", 0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I5 }, {"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, L1 }, +{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P4 }, {"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, G1|M1 }, {"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1 }, {"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, L1 }, +{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P4 }, {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, G1|M1}, {"maddu", "d,s,t", 0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1}, {"madd16", "s,t", 0x00000028, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, V1 }, {"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, I1 }, +{"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, P4 }, {"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I1}, {"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I1}, {"mfc2", "t,G", 0x48000000, 0xffe007ff, LCD|WR_t|RD_C2, I1 }, @@ -550,7 +556,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"movf.d", "D,S,N", 0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I4|M1 }, {"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, I4|M1 }, {"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I5 }, -{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, I4|M1 }, +{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, I4|M1|P4 }, {"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s,L1 }, {"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, I4|M1 }, {"movn.s", "D,S,t", 0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, I4|M1 }, @@ -558,7 +564,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"movt.d", "D,S,N", 0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I4|M1 }, {"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, I4|M1 }, {"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I5}, -{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, I4|M1 }, +{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, I4|M1|P4 }, {"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s,L1 }, {"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, I4|M1 }, {"movz.s", "D,S,t", 0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, I4|M1 }, @@ -567,8 +573,11 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"msub.s", "D,R,S,T", 0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 }, {"msub.ps", "D,R,S,T", 0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I5 }, {"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO,L1 }, +{"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P4 }, {"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO,L1 }, +{"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P4 }, {"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, I1 }, +{"mtc0", "t,G,H", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, P4 }, {"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I1 }, {"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I1 }, {"mtc2", "t,G", 0x48800000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, I1 }, @@ -578,7 +587,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"mul.d", "D,V,T", 0x46200002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I1 }, {"mul.s", "D,V,T", 0x46000002, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, I1 }, {"mul.ps", "D,V,T", 0x46c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I5 }, -{"mul", "d,v,t", 0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HI|WR_LO,P3}, +{"mul", "d,v,t", 0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HI|WR_LO, P3|P4 }, {"mul", "d,v,t", 0, (int) M_MUL, INSN_MACRO, I1 }, {"mul", "d,v,I", 0, (int) M_MUL_I, INSN_MACRO, I1 }, {"mulo", "d,v,t", 0, (int) M_MULO, INSN_MACRO, I1 }, @@ -611,7 +620,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"pll.ps", "D,V,T", 0x46c0002c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I5}, {"plu.ps", "D,V,T", 0x46c0002d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I5}, -{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, G3|M1 }, +{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, G3|M1|P4 }, {"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, I4 }, {"pul.ps", "D,V,T", 0x46c0002e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I5}, @@ -648,6 +657,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"sdbbp", "", 0x0000000e, 0xffffffff, TRAP, G2|M1 }, {"sdbbp", "c", 0x0000000e, 0xfc00ffff, TRAP, G2|M1 }, {"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, G2|M1 }, +{"sdbbp", "m", 0x7000003f, 0xfc00003f, TRAP, P4 }, {"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, I2 }, {"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, I2 }, {"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, I2 }, @@ -755,10 +765,10 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"tgeu", "s,t,q", 0x00000031, 0xfc00003f, RD_s|RD_t|TRAP, I2 }, {"tgeu", "s,j", 0x04090000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tgeiu */ {"tgeu", "s,I", 0, (int) M_TGEU_I, INSN_MACRO, I2 }, -{"tlbp", "", 0x42000008, 0xffffffff, INSN_TLB, I1|M1 }, -{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, I1|M1 }, -{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, I1|M1 }, -{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, I1|M1 }, +{"tlbp", "", 0x42000008, 0xffffffff, INSN_TLB, I1|M1|P4 }, +{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, I1|M1|P4 }, +{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, I1|M1|P4 }, +{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, I1|M1|P4 }, {"tlti", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, I2 }, {"tlt", "s,t", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, I2 }, {"tlt", "s,t,q", 0x00000032, 0xfc00003f, RD_s|RD_t|TRAP, I2 }, @@ -799,7 +809,7 @@ const struct mips_opcode mips_builtin_opcodes[] = { {"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, I1 }, {"xor", "t,r,I", 0, (int) M_XOR_I, INSN_MACRO, I1 }, {"xori", "t,r,i", 0x38000000, 0xfc000000, WR_t|RD_s, I1 }, -{"wait", "", 0x42000020, 0xffffffff, TRAP, I3|M1 }, +{"wait", "", 0x42000020, 0xffffffff, TRAP, I3|M1|P4 }, {"waiti", "", 0x42000020, 0xffffffff, TRAP, L1 }, {"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, L1 }, /* No hazard protection on coprocessor instructions--they shouldn't