[mips patch RFA] some objdump -M options, better reg dumps

cgd@broadcom.com cgd@broadcom.com
Thu Dec 19 21:54:00 GMT 2002


Adds a bunch of disassembly options for use with objdump -M, adds the
ability to diassemble FPU regs using ABI names, adds the ability to
disassemble CP0 regs using symbolic names.

wanted the ability to disable symbolic names for GPRs, wanted the
ability to print symbolic names for CP0 regs.  FPRs i did because they
were easy.  Eventually people will want to give CP2 regs for some
processors and "some other stuff" symbolic disassembly, too.

The defaults for disassembly are the same as before (GPRs according to
ABI, FPRs always numerically), with the exception of CP0 regs which
are now dumped symbolically according to arch/CPU type by default.

This doesn't change any existing testsuite entries since there aren't
CP0 reg name tables for ancient MIPS CPUs.  They weren't so
standardized and since they're not so important to me.  "Excercise for
the reader.  8-)

passes gas/binutils/ld tests w/ no new failures for, uh:

	targets=""
	targets="$targets mips-elf mips64-elf"
	targets="$targets mipsel-elf mips64el-elf"
	targets="$targets mips-linux mips-netbsd"
	targets="$targets mipsel-linux mipsel-netbsd"
	targets="$targets mips64-linux mips64el-linux"
	targets="$targets mipsisa32-elf mipsisa32el-elf"
	targets="$targets mipsisa64-elf mipsisa64el-elf"
	targets="$targets mipsisa64sb1-elf mipsisa64sb1el-elf"
	targets="$targets mips-ecoff mipsel-ecoff"

(yes, that's right, i even tried ecoff!  8-)


FYI:

* ld-elf/merge is failing for the ELF targets, and

* MIPS VR4111, MIPS VR4120, MIPS VR5400, and MIPS VR5500 tests are
  failing for ECOFF now, since objdump opts for those test didn't
  include the arch specs.  (generally better for MIPS bits to test
  disassembly w/ explicit arch flags, and test object file markings on
  a per object file format basis with a separate test.  I'll fix these
  at some point.)


cgd
==
[ binutils/ChangeLog ]
2002-12-19  Chris Demetriou  <cgd@broadcom.com>

	* doc/binutils.texi (objdump): Document MIPS -M options.

[ gas/testsuite/ChangeLog ]
2002-12-19  Chris Demetriou  <cgd@broadcom.com>

	* gas/mips/cp0-names-mips32.d: New file.
	* gas/mips/cp0-names-mips64.d: New file.
	* gas/mips/cp0-names-numeric.d: New file.
	* gas/mips/cp0-names-sb1.d: New file.
	* gas/mips/cp0-names.s: New file.
	* gas/mips/fpr-names-32.d: New file.
	* gas/mips/fpr-names-64.d: New file.
	* gas/mips/fpr-names-n32.d: New file.
	* gas/mips/fpr-names-numeric.d: New file.
	* gas/mips/fpr-names.s: New file.
	* gas/mips/gpr-names-32.d: New file.
	* gas/mips/gpr-names-64.d: New file.
	* gas/mips/gpr-names-n32.d: New file.
	* gas/mips/gpr-names-numeric.d: New file.
	* gas/mips/gpr-names.s: New file.
	* gas/mips/mips.exp: Run new tests.

[ include/ChangeLog ]
2002-12-19  Chris Demetriou  <cgd@broadcom.com>

	* dis-asm.h (print_mips_disassembler_options): Prototype.
 
[ include/opcode/ChangeLog ]
2002-12-19  Chris Demetriou  <cgd@broadcom.com>

	* mips.h (OP_OP_COP0, OP_OP_COP1, OP_OP_COP2, OP_OP_COP3)
	(OP_OP_LWC1, OP_OP_LWC2, OP_OP_LWC3, OP_OP_LDC1, OP_OP_LDC2)
	(OP_OP_LDC3, OP_OP_SWC1, OP_OP_SWC2, OP_OP_SWC3, OP_OP_SDC1)
	(OP_OP_SDC2, OP_OP_SDC3): Define.

[ opcodes/ChangeLog ]
2002-12-19  Chris Demetriou  <cgd@broadcom.com>

	* disassemble.c (disassembler_usage): Add invocation of
	print_mips_disassembler_options.
	* mips-dis.c (print_mips_disassembler_options)
	(set_default_mips_dis_options, parse_mips_dis_option)
	(parse_mips_dis_options, choose_abi_by_name, choose_arch_by_name)
	(choose_arch_by_number): New functions.
	(mips_abi_choice, mips_arch_choice): New structures.
	(mips32_reg_names, mips64_reg_names, reg_names): Remove.
	(mips_gpr_names_numeric, mips_gpr_names_oldabi)
	(mips_gpr_names_newabi, mips_fpr_names_numeric)
	(mips_fpr_names_32, mips_fpr_names_n32, mips_fpr_names_64)
	(mips_cp0_names_numeric, mips_cp0_names_mips3264)
	(mips_cp0_names_sb1, mips_abi_choices, mips_arch_choices)
	(mips_processor, mips_isa, mips_gpr_names, mips_fpr_names)
	(mips_cp0_names): New variables.
	(print_insn_args): Use new variables to print GPR, FPR, and CP0
	register names.
	(mips_isa_type): Remove.
	(print_insn_mips): Remove ISA and CPU setup since it is now done...
	(_print_insn_mips): Here.  Remove register setup code, and
	call set_default_mips_dis_options and parse_mips_dis_options
	instead.
	(print_mips16_insn_arg): Use mips_gpr_names instead of mips32_names.

Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.25
diff -u -p -r1.25 binutils.texi
--- binutils/doc/binutils.texi	19 Dec 2002 14:39:30 -0000	1.25
+++ binutils/doc/binutils.texi	20 Dec 2002 05:01:09 -0000
@@ -1599,6 +1599,42 @@ For PPC, @option{booke}, @option{booke32
 disassembly of BookE instructions.  @option{32} and @option{64} select
 PowerPC and PowerPC64 disassembly, respectively.
 
+For MIPS, this option controls the printing of register names in
+disassembled instructions.  Multiple selections from the
+following may be specified as a comma separated string, and invalid
+options are ignored:
+
+@table @code
+@item gpr-names=@var{ABI}
+Print GPR (general-purpose register) names as appropriate
+for the specified ABI.  By default, GPR names are selected according to
+the ABI of the binary being disassembled.
+
+@item fpr-names=@var{ABI}
+Print FPR (floating-point register) names as
+appropriate for the specified ABI.  By default, FPR numbers are printed
+rather than names.
+
+@item cp0-names=@var{ARCH}
+Print CP0 (system control coprocessor; coprocessor 0) register names
+as appropriate for the CPU or architecture specified by
+@var{ARCH}.  By default, CP0 register names are selected according to
+the architecture and CPU of the binary being disassembled.
+
+@item reg-names=@var{ABI}
+Print both GPR ane FPR names as appropriate for the selected ABI.
+
+@item reg-names=@var{ARCH}
+Print CPU-specific register names (i.e., only the CP0 register names,
+for now) as appropriate for the selected CPU or architecture.
+@end table
+
+For any of the options listed above, @var{ABI} or
+@var{ARCH} may be specified as @samp{numeric} to have numbers printed
+rather than names, for the selected types of registers.
+You can list the available values of @var{ABI} and @var{ARCH} using
+the @option{--help} option.
+
 @item -p
 @itemx --private-headers
 Print information that is specific to the object file format.  The exact
Index: gas/testsuite/gas/mips/cp0-names-mips32.d
===================================================================
RCS file: gas/testsuite/gas/mips/cp0-names-mips32.d
diff -N gas/testsuite/gas/mips/cp0-names-mips32.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/cp0-names-mips32.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,cp0-names=mips32
+#name: MIPS CP0 register disassembly (mips32)
+#source: cp0-names.s
+
+# Check objdump's handling of -M cp0-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 40800000 	mtc0	\$0,c0_index
+0+0004 <[^>]*> 40800800 	mtc0	\$0,c0_random
+0+0008 <[^>]*> 40801000 	mtc0	\$0,c0_entrylo0
+0+000c <[^>]*> 40801800 	mtc0	\$0,c0_entrylo1
+0+0010 <[^>]*> 40802000 	mtc0	\$0,c0_context
+0+0014 <[^>]*> 40802800 	mtc0	\$0,c0_pagemask
+0+0018 <[^>]*> 40803000 	mtc0	\$0,c0_wired
+0+001c <[^>]*> 40803800 	mtc0	\$0,\$7
+0+0020 <[^>]*> 40804000 	mtc0	\$0,c0_badvaddr
+0+0024 <[^>]*> 40804800 	mtc0	\$0,c0_count
+0+0028 <[^>]*> 40805000 	mtc0	\$0,c0_entryhi
+0+002c <[^>]*> 40805800 	mtc0	\$0,c0_compare
+0+0030 <[^>]*> 40806000 	mtc0	\$0,c0_status
+0+0034 <[^>]*> 40806800 	mtc0	\$0,c0_cause
+0+0038 <[^>]*> 40807000 	mtc0	\$0,c0_epc
+0+003c <[^>]*> 40807800 	mtc0	\$0,c0_prid
+0+0040 <[^>]*> 40808000 	mtc0	\$0,c0_config
+0+0044 <[^>]*> 40808800 	mtc0	\$0,c0_lladdr
+0+0048 <[^>]*> 40809000 	mtc0	\$0,c0_watchlo
+0+004c <[^>]*> 40809800 	mtc0	\$0,c0_watchhi
+0+0050 <[^>]*> 4080a000 	mtc0	\$0,c0_xcontext
+0+0054 <[^>]*> 4080a800 	mtc0	\$0,\$21
+0+0058 <[^>]*> 4080b000 	mtc0	\$0,\$22
+0+005c <[^>]*> 4080b800 	mtc0	\$0,c0_debug
+0+0060 <[^>]*> 4080c000 	mtc0	\$0,c0_depc
+0+0064 <[^>]*> 4080c800 	mtc0	\$0,c0_perfcnt
+0+0068 <[^>]*> 4080d000 	mtc0	\$0,c0_errctl
+0+006c <[^>]*> 4080d800 	mtc0	\$0,c0_cacheerr
+0+0070 <[^>]*> 4080e000 	mtc0	\$0,c0_taglo
+0+0074 <[^>]*> 4080e800 	mtc0	\$0,c0_taghi
+0+0078 <[^>]*> 4080f000 	mtc0	\$0,c0_errorepc
+0+007c <[^>]*> 4080f800 	mtc0	\$0,c0_desave
+	\.\.\.
Index: gas/testsuite/gas/mips/cp0-names-mips64.d
===================================================================
RCS file: gas/testsuite/gas/mips/cp0-names-mips64.d
diff -N gas/testsuite/gas/mips/cp0-names-mips64.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/cp0-names-mips64.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,cp0-names=mips64
+#name: MIPS CP0 register disassembly (mips64)
+#source: cp0-names.s
+
+# Check objdump's handling of -M cp0-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 40800000 	mtc0	\$0,c0_index
+0+0004 <[^>]*> 40800800 	mtc0	\$0,c0_random
+0+0008 <[^>]*> 40801000 	mtc0	\$0,c0_entrylo0
+0+000c <[^>]*> 40801800 	mtc0	\$0,c0_entrylo1
+0+0010 <[^>]*> 40802000 	mtc0	\$0,c0_context
+0+0014 <[^>]*> 40802800 	mtc0	\$0,c0_pagemask
+0+0018 <[^>]*> 40803000 	mtc0	\$0,c0_wired
+0+001c <[^>]*> 40803800 	mtc0	\$0,\$7
+0+0020 <[^>]*> 40804000 	mtc0	\$0,c0_badvaddr
+0+0024 <[^>]*> 40804800 	mtc0	\$0,c0_count
+0+0028 <[^>]*> 40805000 	mtc0	\$0,c0_entryhi
+0+002c <[^>]*> 40805800 	mtc0	\$0,c0_compare
+0+0030 <[^>]*> 40806000 	mtc0	\$0,c0_status
+0+0034 <[^>]*> 40806800 	mtc0	\$0,c0_cause
+0+0038 <[^>]*> 40807000 	mtc0	\$0,c0_epc
+0+003c <[^>]*> 40807800 	mtc0	\$0,c0_prid
+0+0040 <[^>]*> 40808000 	mtc0	\$0,c0_config
+0+0044 <[^>]*> 40808800 	mtc0	\$0,c0_lladdr
+0+0048 <[^>]*> 40809000 	mtc0	\$0,c0_watchlo
+0+004c <[^>]*> 40809800 	mtc0	\$0,c0_watchhi
+0+0050 <[^>]*> 4080a000 	mtc0	\$0,c0_xcontext
+0+0054 <[^>]*> 4080a800 	mtc0	\$0,\$21
+0+0058 <[^>]*> 4080b000 	mtc0	\$0,\$22
+0+005c <[^>]*> 4080b800 	mtc0	\$0,c0_debug
+0+0060 <[^>]*> 4080c000 	mtc0	\$0,c0_depc
+0+0064 <[^>]*> 4080c800 	mtc0	\$0,c0_perfcnt
+0+0068 <[^>]*> 4080d000 	mtc0	\$0,c0_errctl
+0+006c <[^>]*> 4080d800 	mtc0	\$0,c0_cacheerr
+0+0070 <[^>]*> 4080e000 	mtc0	\$0,c0_taglo
+0+0074 <[^>]*> 4080e800 	mtc0	\$0,c0_taghi
+0+0078 <[^>]*> 4080f000 	mtc0	\$0,c0_errorepc
+0+007c <[^>]*> 4080f800 	mtc0	\$0,c0_desave
+	\.\.\.
Index: gas/testsuite/gas/mips/cp0-names-numeric.d
===================================================================
RCS file: gas/testsuite/gas/mips/cp0-names-numeric.d
diff -N gas/testsuite/gas/mips/cp0-names-numeric.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/cp0-names-numeric.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,cp0-names=numeric
+#name: MIPS CP0 register disassembly (numeric)
+#source: cp0-names.s
+
+# Check objdump's handling of -M cp0-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 40800000 	mtc0	\$0,\$0
+0+0004 <[^>]*> 40800800 	mtc0	\$0,\$1
+0+0008 <[^>]*> 40801000 	mtc0	\$0,\$2
+0+000c <[^>]*> 40801800 	mtc0	\$0,\$3
+0+0010 <[^>]*> 40802000 	mtc0	\$0,\$4
+0+0014 <[^>]*> 40802800 	mtc0	\$0,\$5
+0+0018 <[^>]*> 40803000 	mtc0	\$0,\$6
+0+001c <[^>]*> 40803800 	mtc0	\$0,\$7
+0+0020 <[^>]*> 40804000 	mtc0	\$0,\$8
+0+0024 <[^>]*> 40804800 	mtc0	\$0,\$9
+0+0028 <[^>]*> 40805000 	mtc0	\$0,\$10
+0+002c <[^>]*> 40805800 	mtc0	\$0,\$11
+0+0030 <[^>]*> 40806000 	mtc0	\$0,\$12
+0+0034 <[^>]*> 40806800 	mtc0	\$0,\$13
+0+0038 <[^>]*> 40807000 	mtc0	\$0,\$14
+0+003c <[^>]*> 40807800 	mtc0	\$0,\$15
+0+0040 <[^>]*> 40808000 	mtc0	\$0,\$16
+0+0044 <[^>]*> 40808800 	mtc0	\$0,\$17
+0+0048 <[^>]*> 40809000 	mtc0	\$0,\$18
+0+004c <[^>]*> 40809800 	mtc0	\$0,\$19
+0+0050 <[^>]*> 4080a000 	mtc0	\$0,\$20
+0+0054 <[^>]*> 4080a800 	mtc0	\$0,\$21
+0+0058 <[^>]*> 4080b000 	mtc0	\$0,\$22
+0+005c <[^>]*> 4080b800 	mtc0	\$0,\$23
+0+0060 <[^>]*> 4080c000 	mtc0	\$0,\$24
+0+0064 <[^>]*> 4080c800 	mtc0	\$0,\$25
+0+0068 <[^>]*> 4080d000 	mtc0	\$0,\$26
+0+006c <[^>]*> 4080d800 	mtc0	\$0,\$27
+0+0070 <[^>]*> 4080e000 	mtc0	\$0,\$28
+0+0074 <[^>]*> 4080e800 	mtc0	\$0,\$29
+0+0078 <[^>]*> 4080f000 	mtc0	\$0,\$30
+0+007c <[^>]*> 4080f800 	mtc0	\$0,\$31
+	\.\.\.
Index: gas/testsuite/gas/mips/cp0-names-sb1.d
===================================================================
RCS file: gas/testsuite/gas/mips/cp0-names-sb1.d
diff -N gas/testsuite/gas/mips/cp0-names-sb1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/cp0-names-sb1.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,cp0-names=sb1
+#name: MIPS CP0 register disassembly (sb1)
+#source: cp0-names.s
+
+# Check objdump's handling of -M cp0-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 40800000 	mtc0	\$0,c0_index
+0+0004 <[^>]*> 40800800 	mtc0	\$0,c0_random
+0+0008 <[^>]*> 40801000 	mtc0	\$0,c0_entrylo0
+0+000c <[^>]*> 40801800 	mtc0	\$0,c0_entrylo1
+0+0010 <[^>]*> 40802000 	mtc0	\$0,c0_context
+0+0014 <[^>]*> 40802800 	mtc0	\$0,c0_pagemask
+0+0018 <[^>]*> 40803000 	mtc0	\$0,c0_wired
+0+001c <[^>]*> 40803800 	mtc0	\$0,\$7
+0+0020 <[^>]*> 40804000 	mtc0	\$0,c0_badvaddr
+0+0024 <[^>]*> 40804800 	mtc0	\$0,c0_count
+0+0028 <[^>]*> 40805000 	mtc0	\$0,c0_entryhi
+0+002c <[^>]*> 40805800 	mtc0	\$0,c0_compare
+0+0030 <[^>]*> 40806000 	mtc0	\$0,c0_status
+0+0034 <[^>]*> 40806800 	mtc0	\$0,c0_cause
+0+0038 <[^>]*> 40807000 	mtc0	\$0,c0_epc
+0+003c <[^>]*> 40807800 	mtc0	\$0,c0_prid
+0+0040 <[^>]*> 40808000 	mtc0	\$0,c0_config
+0+0044 <[^>]*> 40808800 	mtc0	\$0,c0_lladdr
+0+0048 <[^>]*> 40809000 	mtc0	\$0,c0_watchlo
+0+004c <[^>]*> 40809800 	mtc0	\$0,c0_watchhi
+0+0050 <[^>]*> 4080a000 	mtc0	\$0,c0_xcontext
+0+0054 <[^>]*> 4080a800 	mtc0	\$0,\$21
+0+0058 <[^>]*> 4080b000 	mtc0	\$0,\$22
+0+005c <[^>]*> 4080b800 	mtc0	\$0,c0_debug
+0+0060 <[^>]*> 4080c000 	mtc0	\$0,c0_depc
+0+0064 <[^>]*> 4080c800 	mtc0	\$0,c0_perfcnt
+0+0068 <[^>]*> 4080d000 	mtc0	\$0,c0_errctl
+0+006c <[^>]*> 4080d800 	mtc0	\$0,c0_cacheerr_i
+0+0070 <[^>]*> 4080e000 	mtc0	\$0,c0_taglo_i
+0+0074 <[^>]*> 4080e800 	mtc0	\$0,c0_taghi_i
+0+0078 <[^>]*> 4080f000 	mtc0	\$0,c0_errorepc
+0+007c <[^>]*> 4080f800 	mtc0	\$0,c0_desave
+	\.\.\.
Index: gas/testsuite/gas/mips/cp0-names.s
===================================================================
RCS file: gas/testsuite/gas/mips/cp0-names.s
diff -N gas/testsuite/gas/mips/cp0-names.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/cp0-names.s	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,44 @@
+# source file to test objdump's disassembly using various styles of
+# CP0 register names.
+
+	.set noreorder
+	.set noat
+
+	.globl text_label .text
+text_label:
+
+	mtc0	$0, $0
+	mtc0	$0, $1
+	mtc0	$0, $2
+	mtc0	$0, $3
+	mtc0	$0, $4
+	mtc0	$0, $5
+	mtc0	$0, $6
+	mtc0	$0, $7
+	mtc0	$0, $8
+	mtc0	$0, $9
+	mtc0	$0, $10
+	mtc0	$0, $11
+	mtc0	$0, $12
+	mtc0	$0, $13
+	mtc0	$0, $14
+	mtc0	$0, $15
+	mtc0	$0, $16
+	mtc0	$0, $17
+	mtc0	$0, $18
+	mtc0	$0, $19
+	mtc0	$0, $20
+	mtc0	$0, $21
+	mtc0	$0, $22
+	mtc0	$0, $23
+	mtc0	$0, $24
+	mtc0	$0, $25
+	mtc0	$0, $26
+	mtc0	$0, $27
+	mtc0	$0, $28
+	mtc0	$0, $29
+	mtc0	$0, $30
+	mtc0	$0, $31
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+      .space  8
Index: gas/testsuite/gas/mips/fpr-names-32.d
===================================================================
RCS file: gas/testsuite/gas/mips/fpr-names-32.d
diff -N gas/testsuite/gas/mips/fpr-names-32.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/fpr-names-32.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,fpr-names=32
+#name: MIPS FPR disassembly (32)
+#source: fpr-names.s
+
+# Check objdump's handling of -M fpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 44800000 	mtc1	\$0,fv0
+0+0004 <[^>]*> 44800800 	mtc1	\$0,fv0f
+0+0008 <[^>]*> 44801000 	mtc1	\$0,fv1
+0+000c <[^>]*> 44801800 	mtc1	\$0,fv1f
+0+0010 <[^>]*> 44802000 	mtc1	\$0,ft0
+0+0014 <[^>]*> 44802800 	mtc1	\$0,ft0f
+0+0018 <[^>]*> 44803000 	mtc1	\$0,ft1
+0+001c <[^>]*> 44803800 	mtc1	\$0,ft1f
+0+0020 <[^>]*> 44804000 	mtc1	\$0,ft2
+0+0024 <[^>]*> 44804800 	mtc1	\$0,ft2f
+0+0028 <[^>]*> 44805000 	mtc1	\$0,ft3
+0+002c <[^>]*> 44805800 	mtc1	\$0,ft3f
+0+0030 <[^>]*> 44806000 	mtc1	\$0,fa0
+0+0034 <[^>]*> 44806800 	mtc1	\$0,fa0f
+0+0038 <[^>]*> 44807000 	mtc1	\$0,fa1
+0+003c <[^>]*> 44807800 	mtc1	\$0,fa1f
+0+0040 <[^>]*> 44808000 	mtc1	\$0,ft4
+0+0044 <[^>]*> 44808800 	mtc1	\$0,ft4f
+0+0048 <[^>]*> 44809000 	mtc1	\$0,ft5
+0+004c <[^>]*> 44809800 	mtc1	\$0,ft5f
+0+0050 <[^>]*> 4480a000 	mtc1	\$0,fs0
+0+0054 <[^>]*> 4480a800 	mtc1	\$0,fs0f
+0+0058 <[^>]*> 4480b000 	mtc1	\$0,fs1
+0+005c <[^>]*> 4480b800 	mtc1	\$0,fs1f
+0+0060 <[^>]*> 4480c000 	mtc1	\$0,fs2
+0+0064 <[^>]*> 4480c800 	mtc1	\$0,fs2f
+0+0068 <[^>]*> 4480d000 	mtc1	\$0,fs3
+0+006c <[^>]*> 4480d800 	mtc1	\$0,fs3f
+0+0070 <[^>]*> 4480e000 	mtc1	\$0,fs4
+0+0074 <[^>]*> 4480e800 	mtc1	\$0,fs4f
+0+0078 <[^>]*> 4480f000 	mtc1	\$0,fs5
+0+007c <[^>]*> 4480f800 	mtc1	\$0,fs5f
+	\.\.\.
Index: gas/testsuite/gas/mips/fpr-names-64.d
===================================================================
RCS file: gas/testsuite/gas/mips/fpr-names-64.d
diff -N gas/testsuite/gas/mips/fpr-names-64.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/fpr-names-64.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,fpr-names=64
+#name: MIPS FPR disassembly (64)
+#source: fpr-names.s
+
+# Check objdump's handling of -M fpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 44800000 	mtc1	\$0,fv0
+0+0004 <[^>]*> 44800800 	mtc1	\$0,ft12
+0+0008 <[^>]*> 44801000 	mtc1	\$0,fv1
+0+000c <[^>]*> 44801800 	mtc1	\$0,ft13
+0+0010 <[^>]*> 44802000 	mtc1	\$0,ft0
+0+0014 <[^>]*> 44802800 	mtc1	\$0,ft1
+0+0018 <[^>]*> 44803000 	mtc1	\$0,ft2
+0+001c <[^>]*> 44803800 	mtc1	\$0,ft3
+0+0020 <[^>]*> 44804000 	mtc1	\$0,ft4
+0+0024 <[^>]*> 44804800 	mtc1	\$0,ft5
+0+0028 <[^>]*> 44805000 	mtc1	\$0,ft6
+0+002c <[^>]*> 44805800 	mtc1	\$0,ft7
+0+0030 <[^>]*> 44806000 	mtc1	\$0,fa0
+0+0034 <[^>]*> 44806800 	mtc1	\$0,fa1
+0+0038 <[^>]*> 44807000 	mtc1	\$0,fa2
+0+003c <[^>]*> 44807800 	mtc1	\$0,fa3
+0+0040 <[^>]*> 44808000 	mtc1	\$0,fa4
+0+0044 <[^>]*> 44808800 	mtc1	\$0,fa5
+0+0048 <[^>]*> 44809000 	mtc1	\$0,fa6
+0+004c <[^>]*> 44809800 	mtc1	\$0,fa7
+0+0050 <[^>]*> 4480a000 	mtc1	\$0,ft8
+0+0054 <[^>]*> 4480a800 	mtc1	\$0,ft9
+0+0058 <[^>]*> 4480b000 	mtc1	\$0,ft10
+0+005c <[^>]*> 4480b800 	mtc1	\$0,ft11
+0+0060 <[^>]*> 4480c000 	mtc1	\$0,fs0
+0+0064 <[^>]*> 4480c800 	mtc1	\$0,fs1
+0+0068 <[^>]*> 4480d000 	mtc1	\$0,fs2
+0+006c <[^>]*> 4480d800 	mtc1	\$0,fs3
+0+0070 <[^>]*> 4480e000 	mtc1	\$0,fs4
+0+0074 <[^>]*> 4480e800 	mtc1	\$0,fs5
+0+0078 <[^>]*> 4480f000 	mtc1	\$0,fs6
+0+007c <[^>]*> 4480f800 	mtc1	\$0,fs7
+	\.\.\.
Index: gas/testsuite/gas/mips/fpr-names-n32.d
===================================================================
RCS file: gas/testsuite/gas/mips/fpr-names-n32.d
diff -N gas/testsuite/gas/mips/fpr-names-n32.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/fpr-names-n32.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,fpr-names=n32
+#name: MIPS FPR disassembly (n32)
+#source: fpr-names.s
+
+# Check objdump's handling of -M fpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 44800000 	mtc1	\$0,fv0
+0+0004 <[^>]*> 44800800 	mtc1	\$0,ft14
+0+0008 <[^>]*> 44801000 	mtc1	\$0,fv1
+0+000c <[^>]*> 44801800 	mtc1	\$0,ft15
+0+0010 <[^>]*> 44802000 	mtc1	\$0,ft0
+0+0014 <[^>]*> 44802800 	mtc1	\$0,ft1
+0+0018 <[^>]*> 44803000 	mtc1	\$0,ft2
+0+001c <[^>]*> 44803800 	mtc1	\$0,ft3
+0+0020 <[^>]*> 44804000 	mtc1	\$0,ft4
+0+0024 <[^>]*> 44804800 	mtc1	\$0,ft5
+0+0028 <[^>]*> 44805000 	mtc1	\$0,ft6
+0+002c <[^>]*> 44805800 	mtc1	\$0,ft7
+0+0030 <[^>]*> 44806000 	mtc1	\$0,fa0
+0+0034 <[^>]*> 44806800 	mtc1	\$0,fa1
+0+0038 <[^>]*> 44807000 	mtc1	\$0,fa2
+0+003c <[^>]*> 44807800 	mtc1	\$0,fa3
+0+0040 <[^>]*> 44808000 	mtc1	\$0,fa4
+0+0044 <[^>]*> 44808800 	mtc1	\$0,fa5
+0+0048 <[^>]*> 44809000 	mtc1	\$0,fa6
+0+004c <[^>]*> 44809800 	mtc1	\$0,fa7
+0+0050 <[^>]*> 4480a000 	mtc1	\$0,fs0
+0+0054 <[^>]*> 4480a800 	mtc1	\$0,ft8
+0+0058 <[^>]*> 4480b000 	mtc1	\$0,fs1
+0+005c <[^>]*> 4480b800 	mtc1	\$0,ft9
+0+0060 <[^>]*> 4480c000 	mtc1	\$0,fs2
+0+0064 <[^>]*> 4480c800 	mtc1	\$0,ft10
+0+0068 <[^>]*> 4480d000 	mtc1	\$0,fs3
+0+006c <[^>]*> 4480d800 	mtc1	\$0,ft11
+0+0070 <[^>]*> 4480e000 	mtc1	\$0,fs4
+0+0074 <[^>]*> 4480e800 	mtc1	\$0,ft12
+0+0078 <[^>]*> 4480f000 	mtc1	\$0,fs5
+0+007c <[^>]*> 4480f800 	mtc1	\$0,ft13
+	\.\.\.
Index: gas/testsuite/gas/mips/fpr-names-numeric.d
===================================================================
RCS file: gas/testsuite/gas/mips/fpr-names-numeric.d
diff -N gas/testsuite/gas/mips/fpr-names-numeric.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/fpr-names-numeric.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric,fpr-names=numeric
+#name: MIPS FPR disassembly (numeric)
+#source: fpr-names.s
+
+# Check objdump's handling of -M fpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 44800000 	mtc1	\$0,\$f0
+0+0004 <[^>]*> 44800800 	mtc1	\$0,\$f1
+0+0008 <[^>]*> 44801000 	mtc1	\$0,\$f2
+0+000c <[^>]*> 44801800 	mtc1	\$0,\$f3
+0+0010 <[^>]*> 44802000 	mtc1	\$0,\$f4
+0+0014 <[^>]*> 44802800 	mtc1	\$0,\$f5
+0+0018 <[^>]*> 44803000 	mtc1	\$0,\$f6
+0+001c <[^>]*> 44803800 	mtc1	\$0,\$f7
+0+0020 <[^>]*> 44804000 	mtc1	\$0,\$f8
+0+0024 <[^>]*> 44804800 	mtc1	\$0,\$f9
+0+0028 <[^>]*> 44805000 	mtc1	\$0,\$f10
+0+002c <[^>]*> 44805800 	mtc1	\$0,\$f11
+0+0030 <[^>]*> 44806000 	mtc1	\$0,\$f12
+0+0034 <[^>]*> 44806800 	mtc1	\$0,\$f13
+0+0038 <[^>]*> 44807000 	mtc1	\$0,\$f14
+0+003c <[^>]*> 44807800 	mtc1	\$0,\$f15
+0+0040 <[^>]*> 44808000 	mtc1	\$0,\$f16
+0+0044 <[^>]*> 44808800 	mtc1	\$0,\$f17
+0+0048 <[^>]*> 44809000 	mtc1	\$0,\$f18
+0+004c <[^>]*> 44809800 	mtc1	\$0,\$f19
+0+0050 <[^>]*> 4480a000 	mtc1	\$0,\$f20
+0+0054 <[^>]*> 4480a800 	mtc1	\$0,\$f21
+0+0058 <[^>]*> 4480b000 	mtc1	\$0,\$f22
+0+005c <[^>]*> 4480b800 	mtc1	\$0,\$f23
+0+0060 <[^>]*> 4480c000 	mtc1	\$0,\$f24
+0+0064 <[^>]*> 4480c800 	mtc1	\$0,\$f25
+0+0068 <[^>]*> 4480d000 	mtc1	\$0,\$f26
+0+006c <[^>]*> 4480d800 	mtc1	\$0,\$f27
+0+0070 <[^>]*> 4480e000 	mtc1	\$0,\$f28
+0+0074 <[^>]*> 4480e800 	mtc1	\$0,\$f29
+0+0078 <[^>]*> 4480f000 	mtc1	\$0,\$f30
+0+007c <[^>]*> 4480f800 	mtc1	\$0,\$f31
+	\.\.\.
Index: gas/testsuite/gas/mips/fpr-names.s
===================================================================
RCS file: gas/testsuite/gas/mips/fpr-names.s
diff -N gas/testsuite/gas/mips/fpr-names.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/fpr-names.s	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,44 @@
+# source file to test objdump's disassembly using various styles of
+# FPR names.
+
+	.set noreorder
+	.set noat
+
+	.globl text_label .text
+text_label:
+
+	mtc1	$0, $f0
+	mtc1	$0, $f1
+	mtc1	$0, $f2
+	mtc1	$0, $f3
+	mtc1	$0, $f4
+	mtc1	$0, $f5
+	mtc1	$0, $f6
+	mtc1	$0, $f7
+	mtc1	$0, $f8
+	mtc1	$0, $f9
+	mtc1	$0, $f10
+	mtc1	$0, $f11
+	mtc1	$0, $f12
+	mtc1	$0, $f13
+	mtc1	$0, $f14
+	mtc1	$0, $f15
+	mtc1	$0, $f16
+	mtc1	$0, $f17
+	mtc1	$0, $f18
+	mtc1	$0, $f19
+	mtc1	$0, $f20
+	mtc1	$0, $f21
+	mtc1	$0, $f22
+	mtc1	$0, $f23
+	mtc1	$0, $f24
+	mtc1	$0, $f25
+	mtc1	$0, $f26
+	mtc1	$0, $f27
+	mtc1	$0, $f28
+	mtc1	$0, $f29
+	mtc1	$0, $f30
+	mtc1	$0, $f31
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+      .space  8
Index: gas/testsuite/gas/mips/gpr-names-32.d
===================================================================
RCS file: gas/testsuite/gas/mips/gpr-names-32.d
diff -N gas/testsuite/gas/mips/gpr-names-32.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/gpr-names-32.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=32
+#name: MIPS GPR disassembly (32)
+#source: gpr-names.s
+
+# Check objdump's handling of -M gpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 3c000000 	lui	zero,0x0
+0+0004 <[^>]*> 3c010000 	lui	at,0x0
+0+0008 <[^>]*> 3c020000 	lui	v0,0x0
+0+000c <[^>]*> 3c030000 	lui	v1,0x0
+0+0010 <[^>]*> 3c040000 	lui	a0,0x0
+0+0014 <[^>]*> 3c050000 	lui	a1,0x0
+0+0018 <[^>]*> 3c060000 	lui	a2,0x0
+0+001c <[^>]*> 3c070000 	lui	a3,0x0
+0+0020 <[^>]*> 3c080000 	lui	t0,0x0
+0+0024 <[^>]*> 3c090000 	lui	t1,0x0
+0+0028 <[^>]*> 3c0a0000 	lui	t2,0x0
+0+002c <[^>]*> 3c0b0000 	lui	t3,0x0
+0+0030 <[^>]*> 3c0c0000 	lui	t4,0x0
+0+0034 <[^>]*> 3c0d0000 	lui	t5,0x0
+0+0038 <[^>]*> 3c0e0000 	lui	t6,0x0
+0+003c <[^>]*> 3c0f0000 	lui	t7,0x0
+0+0040 <[^>]*> 3c100000 	lui	s0,0x0
+0+0044 <[^>]*> 3c110000 	lui	s1,0x0
+0+0048 <[^>]*> 3c120000 	lui	s2,0x0
+0+004c <[^>]*> 3c130000 	lui	s3,0x0
+0+0050 <[^>]*> 3c140000 	lui	s4,0x0
+0+0054 <[^>]*> 3c150000 	lui	s5,0x0
+0+0058 <[^>]*> 3c160000 	lui	s6,0x0
+0+005c <[^>]*> 3c170000 	lui	s7,0x0
+0+0060 <[^>]*> 3c180000 	lui	t8,0x0
+0+0064 <[^>]*> 3c190000 	lui	t9,0x0
+0+0068 <[^>]*> 3c1a0000 	lui	k0,0x0
+0+006c <[^>]*> 3c1b0000 	lui	k1,0x0
+0+0070 <[^>]*> 3c1c0000 	lui	gp,0x0
+0+0074 <[^>]*> 3c1d0000 	lui	sp,0x0
+0+0078 <[^>]*> 3c1e0000 	lui	s8,0x0
+0+007c <[^>]*> 3c1f0000 	lui	ra,0x0
+	\.\.\.
Index: gas/testsuite/gas/mips/gpr-names-64.d
===================================================================
RCS file: gas/testsuite/gas/mips/gpr-names-64.d
diff -N gas/testsuite/gas/mips/gpr-names-64.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/gpr-names-64.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=64
+#name: MIPS GPR disassembly (64)
+#source: gpr-names.s
+
+# Check objdump's handling of -M gpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 3c000000 	lui	zero,0x0
+0+0004 <[^>]*> 3c010000 	lui	at,0x0
+0+0008 <[^>]*> 3c020000 	lui	v0,0x0
+0+000c <[^>]*> 3c030000 	lui	v1,0x0
+0+0010 <[^>]*> 3c040000 	lui	a0,0x0
+0+0014 <[^>]*> 3c050000 	lui	a1,0x0
+0+0018 <[^>]*> 3c060000 	lui	a2,0x0
+0+001c <[^>]*> 3c070000 	lui	a3,0x0
+0+0020 <[^>]*> 3c080000 	lui	a4,0x0
+0+0024 <[^>]*> 3c090000 	lui	a5,0x0
+0+0028 <[^>]*> 3c0a0000 	lui	a6,0x0
+0+002c <[^>]*> 3c0b0000 	lui	a7,0x0
+0+0030 <[^>]*> 3c0c0000 	lui	t0,0x0
+0+0034 <[^>]*> 3c0d0000 	lui	t1,0x0
+0+0038 <[^>]*> 3c0e0000 	lui	t2,0x0
+0+003c <[^>]*> 3c0f0000 	lui	t3,0x0
+0+0040 <[^>]*> 3c100000 	lui	s0,0x0
+0+0044 <[^>]*> 3c110000 	lui	s1,0x0
+0+0048 <[^>]*> 3c120000 	lui	s2,0x0
+0+004c <[^>]*> 3c130000 	lui	s3,0x0
+0+0050 <[^>]*> 3c140000 	lui	s4,0x0
+0+0054 <[^>]*> 3c150000 	lui	s5,0x0
+0+0058 <[^>]*> 3c160000 	lui	s6,0x0
+0+005c <[^>]*> 3c170000 	lui	s7,0x0
+0+0060 <[^>]*> 3c180000 	lui	t8,0x0
+0+0064 <[^>]*> 3c190000 	lui	t9,0x0
+0+0068 <[^>]*> 3c1a0000 	lui	k0,0x0
+0+006c <[^>]*> 3c1b0000 	lui	k1,0x0
+0+0070 <[^>]*> 3c1c0000 	lui	gp,0x0
+0+0074 <[^>]*> 3c1d0000 	lui	sp,0x0
+0+0078 <[^>]*> 3c1e0000 	lui	s8,0x0
+0+007c <[^>]*> 3c1f0000 	lui	ra,0x0
+	\.\.\.
Index: gas/testsuite/gas/mips/gpr-names-n32.d
===================================================================
RCS file: gas/testsuite/gas/mips/gpr-names-n32.d
diff -N gas/testsuite/gas/mips/gpr-names-n32.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/gpr-names-n32.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=n32
+#name: MIPS GPR disassembly (n32)
+#source: gpr-names.s
+
+# Check objdump's handling of -M gpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 3c000000 	lui	zero,0x0
+0+0004 <[^>]*> 3c010000 	lui	at,0x0
+0+0008 <[^>]*> 3c020000 	lui	v0,0x0
+0+000c <[^>]*> 3c030000 	lui	v1,0x0
+0+0010 <[^>]*> 3c040000 	lui	a0,0x0
+0+0014 <[^>]*> 3c050000 	lui	a1,0x0
+0+0018 <[^>]*> 3c060000 	lui	a2,0x0
+0+001c <[^>]*> 3c070000 	lui	a3,0x0
+0+0020 <[^>]*> 3c080000 	lui	a4,0x0
+0+0024 <[^>]*> 3c090000 	lui	a5,0x0
+0+0028 <[^>]*> 3c0a0000 	lui	a6,0x0
+0+002c <[^>]*> 3c0b0000 	lui	a7,0x0
+0+0030 <[^>]*> 3c0c0000 	lui	t0,0x0
+0+0034 <[^>]*> 3c0d0000 	lui	t1,0x0
+0+0038 <[^>]*> 3c0e0000 	lui	t2,0x0
+0+003c <[^>]*> 3c0f0000 	lui	t3,0x0
+0+0040 <[^>]*> 3c100000 	lui	s0,0x0
+0+0044 <[^>]*> 3c110000 	lui	s1,0x0
+0+0048 <[^>]*> 3c120000 	lui	s2,0x0
+0+004c <[^>]*> 3c130000 	lui	s3,0x0
+0+0050 <[^>]*> 3c140000 	lui	s4,0x0
+0+0054 <[^>]*> 3c150000 	lui	s5,0x0
+0+0058 <[^>]*> 3c160000 	lui	s6,0x0
+0+005c <[^>]*> 3c170000 	lui	s7,0x0
+0+0060 <[^>]*> 3c180000 	lui	t8,0x0
+0+0064 <[^>]*> 3c190000 	lui	t9,0x0
+0+0068 <[^>]*> 3c1a0000 	lui	k0,0x0
+0+006c <[^>]*> 3c1b0000 	lui	k1,0x0
+0+0070 <[^>]*> 3c1c0000 	lui	gp,0x0
+0+0074 <[^>]*> 3c1d0000 	lui	sp,0x0
+0+0078 <[^>]*> 3c1e0000 	lui	s8,0x0
+0+007c <[^>]*> 3c1f0000 	lui	ra,0x0
+	\.\.\.
Index: gas/testsuite/gas/mips/gpr-names-numeric.d
===================================================================
RCS file: gas/testsuite/gas/mips/gpr-names-numeric.d
diff -N gas/testsuite/gas/mips/gpr-names-numeric.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/gpr-names-numeric.d	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric
+#name: MIPS GPR disassembly (numeric)
+#source: gpr-names.s
+
+# Check objdump's handling of -M gpr-names=foo options.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 3c000000 	lui	\$0,0x0
+0+0004 <[^>]*> 3c010000 	lui	\$1,0x0
+0+0008 <[^>]*> 3c020000 	lui	\$2,0x0
+0+000c <[^>]*> 3c030000 	lui	\$3,0x0
+0+0010 <[^>]*> 3c040000 	lui	\$4,0x0
+0+0014 <[^>]*> 3c050000 	lui	\$5,0x0
+0+0018 <[^>]*> 3c060000 	lui	\$6,0x0
+0+001c <[^>]*> 3c070000 	lui	\$7,0x0
+0+0020 <[^>]*> 3c080000 	lui	\$8,0x0
+0+0024 <[^>]*> 3c090000 	lui	\$9,0x0
+0+0028 <[^>]*> 3c0a0000 	lui	\$10,0x0
+0+002c <[^>]*> 3c0b0000 	lui	\$11,0x0
+0+0030 <[^>]*> 3c0c0000 	lui	\$12,0x0
+0+0034 <[^>]*> 3c0d0000 	lui	\$13,0x0
+0+0038 <[^>]*> 3c0e0000 	lui	\$14,0x0
+0+003c <[^>]*> 3c0f0000 	lui	\$15,0x0
+0+0040 <[^>]*> 3c100000 	lui	\$16,0x0
+0+0044 <[^>]*> 3c110000 	lui	\$17,0x0
+0+0048 <[^>]*> 3c120000 	lui	\$18,0x0
+0+004c <[^>]*> 3c130000 	lui	\$19,0x0
+0+0050 <[^>]*> 3c140000 	lui	\$20,0x0
+0+0054 <[^>]*> 3c150000 	lui	\$21,0x0
+0+0058 <[^>]*> 3c160000 	lui	\$22,0x0
+0+005c <[^>]*> 3c170000 	lui	\$23,0x0
+0+0060 <[^>]*> 3c180000 	lui	\$24,0x0
+0+0064 <[^>]*> 3c190000 	lui	\$25,0x0
+0+0068 <[^>]*> 3c1a0000 	lui	\$26,0x0
+0+006c <[^>]*> 3c1b0000 	lui	\$27,0x0
+0+0070 <[^>]*> 3c1c0000 	lui	\$28,0x0
+0+0074 <[^>]*> 3c1d0000 	lui	\$29,0x0
+0+0078 <[^>]*> 3c1e0000 	lui	\$30,0x0
+0+007c <[^>]*> 3c1f0000 	lui	\$31,0x0
+	\.\.\.
Index: gas/testsuite/gas/mips/gpr-names.s
===================================================================
RCS file: gas/testsuite/gas/mips/gpr-names.s
diff -N gas/testsuite/gas/mips/gpr-names.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/gpr-names.s	20 Dec 2002 05:01:11 -0000
@@ -0,0 +1,44 @@
+# source file to test objdump's disassembly using various styles of
+# GPR names.
+
+	.set noreorder
+	.set noat
+
+	.globl text_label .text
+text_label:
+
+	lui	$0, 0
+	lui	$1, 0
+	lui	$2, 0
+	lui	$3, 0
+	lui	$4, 0
+	lui	$5, 0
+	lui	$6, 0
+	lui	$7, 0
+	lui	$8, 0
+	lui	$9, 0
+	lui	$10, 0
+	lui	$11, 0
+	lui	$12, 0
+	lui	$13, 0
+	lui	$14, 0
+	lui	$15, 0
+	lui	$16, 0
+	lui	$17, 0
+	lui	$18, 0
+	lui	$19, 0
+	lui	$20, 0
+	lui	$21, 0
+	lui	$22, 0
+	lui	$23, 0
+	lui	$24, 0
+	lui	$25, 0
+	lui	$26, 0
+	lui	$27, 0
+	lui	$28, 0
+	lui	$29, 0
+	lui	$30, 0
+	lui	$31, 0
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+      .space  8
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.52
diff -u -p -r1.52 mips.exp
--- gas/testsuite/gas/mips/mips.exp	18 Dec 2002 22:52:48 -0000	1.52
+++ gas/testsuite/gas/mips/mips.exp	20 Dec 2002 05:01:11 -0000
@@ -234,4 +234,21 @@ if { [istarget mips*-*-*] } then {
 	}
 	run_dump_test "elf-consthilo"
     }
+
+    # tests of objdump's ability to disassemble using different
+    # register names.
+    run_dump_test "gpr-names-numeric"
+    run_dump_test "gpr-names-32"
+    run_dump_test "gpr-names-n32"
+    run_dump_test "gpr-names-64"
+
+    run_dump_test "fpr-names-numeric"
+    run_dump_test "fpr-names-32"
+    run_dump_test "fpr-names-n32"
+    run_dump_test "fpr-names-64"
+
+    run_dump_test "cp0-names-numeric"
+    run_dump_test "cp0-names-mips32"
+    run_dump_test "cp0-names-mips64"
+    run_dump_test "cp0-names-sb1"
 }
Index: include/dis-asm.h
===================================================================
RCS file: /cvs/src/src/include/dis-asm.h,v
retrieving revision 1.39
diff -u -p -r1.39 dis-asm.h
--- include/dis-asm.h	19 Sep 2002 15:48:16 -0000	1.39
+++ include/dis-asm.h	20 Dec 2002 05:01:13 -0000
@@ -243,6 +243,7 @@ extern int print_insn_frv		PARAMS ((bfd_
 extern disassembler_ftype arc_get_disassembler PARAMS ((void *));
 extern disassembler_ftype cris_get_disassembler PARAMS ((bfd *));
 
+extern void print_mips_disassembler_options PARAMS ((FILE *));
 extern void print_ppc_disassembler_options PARAMS ((FILE *));
 extern void print_arm_disassembler_options PARAMS ((FILE *));
 extern void parse_arm_disassembler_option  PARAMS ((char *));
Index: include/opcode/mips.h
===================================================================
RCS file: /cvs/src/src/include/opcode/mips.h,v
retrieving revision 1.29
diff -u -p -r1.29 mips.h
--- include/opcode/mips.h	30 Sep 2002 11:58:09 -0000	1.29
+++ include/opcode/mips.h	20 Dec 2002 05:01:13 -0000
@@ -143,6 +143,23 @@ Software Foundation, 59 Temple Place - S
 #define OP_MASK_VECALIGN	0x7	/* Vector byte-align (alni.ob) op.  */
 #define OP_SH_VECALIGN		21
 
+#define	OP_OP_COP0		0x10
+#define	OP_OP_COP1		0x11
+#define	OP_OP_COP2		0x12
+#define	OP_OP_COP3		0x13
+#define	OP_OP_LWC1		0x31
+#define	OP_OP_LWC2		0x32
+#define	OP_OP_LWC3		0x33	/* a.k.a. pref */
+#define	OP_OP_LDC1		0x35
+#define	OP_OP_LDC2		0x36
+#define	OP_OP_LDC3		0x37	/* a.k.a. ld */
+#define	OP_OP_SWC1		0x39
+#define	OP_OP_SWC2		0x3a
+#define	OP_OP_SWC3		0x3b
+#define	OP_OP_SDC1		0x3d
+#define	OP_OP_SDC2		0x3e
+#define	OP_OP_SDC3		0x3f	/* a.k.a. sd */
+
 /* Values in the 'VSEL' field.  */
 #define MDMX_FMTSEL_IMM_QH	0x1d
 #define MDMX_FMTSEL_IMM_OB	0x1e
Index: opcodes/disassemble.c
===================================================================
RCS file: /cvs/src/src/opcodes/disassemble.c,v
retrieving revision 1.38
diff -u -p -r1.38 disassemble.c
--- opcodes/disassemble.c	4 Sep 2002 10:08:08 -0000	1.38
+++ opcodes/disassemble.c	20 Dec 2002 05:01:15 -0000
@@ -367,6 +367,9 @@ disassembler_usage (stream)
 #ifdef ARCH_arm
   print_arm_disassembler_options (stream);
 #endif
+#ifdef ARCH_mips
+  print_mips_disassembler_options (stream);
+#endif
 #ifdef ARCH_powerpc
   print_ppc_disassembler_options (stream);
 #endif
Index: opcodes/mips-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/mips-dis.c,v
retrieving revision 1.35
diff -u -p -r1.35 mips-dis.c
--- opcodes/mips-dis.c	30 Nov 2002 08:39:46 -0000	1.35
+++ opcodes/mips-dis.c	20 Dec 2002 05:01:15 -0000
@@ -39,14 +39,18 @@ Foundation, Inc., 59 Temple Place - Suit
 /* Mips instructions are at maximum this many bytes long.  */
 #define INSNLEN 4
 
+static void set_default_mips_dis_options
+  PARAMS ((struct disassemble_info *));
+static void parse_mips_dis_option
+  PARAMS ((const char *, unsigned int));
+static void parse_mips_dis_options
+  PARAMS ((const char *));
 static int _print_insn_mips
   PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
 static int print_insn_mips
   PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
 static void print_insn_arg
   PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
-static void mips_isa_type
-  PARAMS ((int, int *, int *));
 static int print_insn_mips16
   PARAMS ((bfd_vma, struct disassemble_info *));
 static int is_newabi
@@ -62,37 +66,408 @@ static const char * const mips16_reg_nam
   "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
 };
 
-static const char * const mips32_reg_names[] = {
-  "zero", "at",	  "v0",	 "v1",	 "a0",	  "a1",	   "a2",   "a3",
-  "t0",	  "t1",	  "t2",	 "t3",	 "t4",	  "t5",	   "t6",   "t7",
-  "s0",	  "s1",	  "s2",	 "s3",	 "s4",	  "s5",	   "s6",   "s7",
-  "t8",	  "t9",	  "k0",	 "k1",	 "gp",	  "sp",	   "s8",   "ra",
-  "sr",	  "lo",	  "hi",	 "bad",	 "cause", "pc",
-  "fv0",  "$f1",  "fv1", "$f3",  "ft0",   "$f5",   "ft1",  "$f7",
-  "ft2",  "$f9",  "ft3", "$f11", "fa0",   "$f13",  "fa1",  "$f15",
-  "ft4",  "f17",  "ft5", "f19",  "fs0",   "f21",   "fs1",  "f23",
-  "fs2",  "$f25", "fs3", "$f27", "fs4",   "$f29",  "fs5",  "$f31",
-  "fsr",  "fir",  "fp",  "inx",  "rand",  "tlblo", "ctxt", "tlbhi",
-  "epc",  "prid"
+static const char * const mips_gpr_names_numeric[32] = {
+  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
+  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
+  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
+  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
 };
 
-static const char * const mips64_reg_names[] = {
-  "zero", "at",	  "v0",	  "v1",	  "a0",	   "a1",    "a2",   "a3",
-  "a4",	  "a5",	  "a6",   "a7",	  "t0",	   "t1",    "t2",   "t3",
-  "s0",	  "s1",	  "s2",	  "s3",	  "s4",	   "s5",    "s6",   "s7",
-  "t8",	  "t9",	  "k0",	  "k1",	  "gp",	   "sp",    "s8",   "ra",
-  "sr",	  "lo",	  "hi",	  "bad",  "cause", "pc",
-  "fv0",  "$f1",  "fv1",  "$f3",  "ft0",   "ft1",   "ft2",  "ft3",
-  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",   "fa1",   "fa2",  "fa3",
-  "fa4",  "fa5",  "fa6",  "fa7",  "ft8",   "ft9",   "ft10", "ft11",
-  "fs0",  "fs1",  "fs2",  "fs3",  "fs4",   "fs5",   "fs6",  "fs7",
-  "fsr",  "fir",  "fp",   "inx",  "rand",  "tlblo", "ctxt", "tlbhi",
-  "epc",  "prid"
+static const char * const mips_gpr_names_oldabi[32] = {
+  "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
+  "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
+  "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
+  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
 };
 
-/* Scalar register names. _print_insn_mips() decides which register name
-   table to use.  */
-static const char * const *reg_names = NULL;
+static const char * const mips_gpr_names_newabi[32] = {
+  "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
+  "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
+  "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
+  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
+};
+
+static const char * const mips_fpr_names_numeric[32] = {
+  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
+  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
+};
+
+static const char * const mips_fpr_names_32[32] = {
+  "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
+  "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
+  "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
+  "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
+};
+
+static const char * const mips_fpr_names_n32[32] = {
+  "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
+  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
+  "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
+  "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
+};
+
+static const char * const mips_fpr_names_64[32] = {
+  "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
+  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
+  "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
+  "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
+};
+
+static const char * const mips_cp0_names_numeric[32] = {
+  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
+  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
+  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
+  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
+};
+
+static const char * const mips_cp0_names_mips3264[32] = {
+  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
+  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
+  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
+  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
+  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
+  "c0_xcontext",  "$21",          "$22",          "c0_debug",
+  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
+  "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
+};
+
+static const char * const mips_cp0_names_sb1[32] = {
+  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
+  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
+  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
+  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
+  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
+  "c0_xcontext",  "$21",          "$22",          "c0_debug",
+  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
+  "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
+};
+
+struct mips_abi_choice {
+  const char *name;
+  const char * const *gpr_names;
+  const char * const *fpr_names;
+};
+
+struct mips_abi_choice mips_abi_choices[] = {
+  { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
+  { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
+  { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
+  { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
+  { NULL, NULL, NULL }
+};
+
+struct mips_arch_choice {
+  const char *name;
+  int bfd_mach_valid;
+  unsigned long bfd_mach;
+  int processor;
+  int isa;
+  const char * const *cp0_names;
+};
+
+struct mips_arch_choice mips_arch_choices[] = {
+  { "numeric",	0, 0, 0, 0,
+    mips_cp0_names_numeric },
+  { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
+    NULL },
+  { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
+    NULL },
+  { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
+    NULL },
+  { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
+    NULL },
+  { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
+    NULL },
+  { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
+    NULL },
+  { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
+    NULL },
+  { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
+    NULL },
+  { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
+    NULL },
+  { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
+    NULL },
+  { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
+    NULL },
+  { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
+    NULL },
+  { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
+    NULL },
+  { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
+    NULL },
+  { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
+    NULL },
+  { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
+    NULL },
+  { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
+    NULL },
+  { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
+    NULL },
+  { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
+    NULL },
+  /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
+     Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
+     _MIPS32 Architecture For Programmers Volume I: Introduction to the
+     MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
+     page 1.  */
+  { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
+    ISA_MIPS32 | INSN_MIPS16,
+    mips_cp0_names_mips3264 },
+  /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
+  { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
+    ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
+    mips_cp0_names_mips3264 },
+  { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
+    ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
+    mips_cp0_names_sb1 },
+
+  /* This entry, mips16, is here only for ISA/processor selection; do
+     not print its name.  */
+  { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
+    NULL },
+
+  { NULL, 0, 0, 0, 0, NULL }
+};
+
+/* ISA and processor type to disassemble for, and register names to use.
+   set_default_mips_dis_options and parse_mips_dis_options fill in these
+   values.  */
+static int mips_processor;
+static int mips_isa;
+static const char * const *mips_gpr_names;
+static const char * const *mips_fpr_names;
+static const char * const *mips_cp0_names;
+
+static const struct mips_abi_choice *choose_abi_by_name
+  PARAMS ((const char *, unsigned int));
+static const struct mips_arch_choice *choose_arch_by_name
+  PARAMS ((const char *, unsigned int));
+static const struct mips_arch_choice *choose_arch_by_number
+  PARAMS ((unsigned long));
+
+static const struct mips_abi_choice *
+choose_abi_by_name (name, namelen)
+     const char *name;
+     unsigned int namelen;
+{
+  const struct mips_abi_choice *c;
+
+  c = mips_abi_choices;
+  while (c->name != NULL)
+    {
+      if (strncmp (c->name, name, namelen) == 0
+	  && strlen (c->name) == namelen)
+	return c;
+      c++;
+    }
+  return NULL;
+}
+
+static const struct mips_arch_choice *
+choose_arch_by_name (name, namelen)
+     const char *name;
+     unsigned int namelen;
+{
+  const struct mips_arch_choice *c;
+
+  c = mips_arch_choices;
+  while (c->name != NULL)
+    {
+      if (strncmp (c->name, name, namelen) == 0
+	  && strlen (c->name) == namelen)
+	return c;
+      c++;
+    }
+  return NULL;
+}
+
+static const struct mips_arch_choice *
+choose_arch_by_number (mach)
+     unsigned long mach;
+{
+  static unsigned long hint_bfd_mach;
+  static const struct mips_arch_choice *hint_arch_choice;
+  const struct mips_arch_choice *c;
+
+  /* We optimize this because even if the user specifies no
+     flags, this will be done for every instruction!  */
+  if (hint_bfd_mach == mach
+      && hint_arch_choice != NULL
+      && hint_arch_choice->bfd_mach == hint_bfd_mach)
+    return hint_arch_choice;
+
+  c = mips_arch_choices;
+  while (c->name != NULL)
+    {
+      if (c->bfd_mach_valid && c->bfd_mach == mach)
+	{
+	  hint_bfd_mach = mach;
+	  hint_arch_choice = c;
+
+	  return c;
+	}
+      c++;
+    }
+  return NULL;
+}
+
+void
+set_default_mips_dis_options (info)
+     struct disassemble_info *info;
+{
+  const struct mips_arch_choice *chosen_arch;
+
+  /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
+     and numeric FPR and CP0 register names.  */
+  mips_isa = ISA_MIPS3;
+  mips_processor =  CPU_R3000;
+  mips_gpr_names = mips_gpr_names_oldabi;
+  mips_fpr_names = mips_fpr_names_numeric;
+  mips_cp0_names = mips_cp0_names_numeric;
+
+  /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
+  if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
+    {
+      Elf_Internal_Ehdr *header;
+
+      header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
+      if (is_newabi (header))
+	mips_gpr_names = mips_gpr_names_newabi;
+    }
+
+  /* Set ISA, architecture, and cp0 register names as best we can.  */
+#if ! SYMTAB_AVAILABLE
+  /* This is running out on a target machine, not in a host tool.
+     FIXME: Where does mips_target_info come from?  */
+  target_processor = mips_target_info.processor;
+  mips_isa = mips_target_info.isa;
+#else
+  chosen_arch = choose_arch_by_number (info->mach);
+  if (chosen_arch != NULL)
+    {
+      mips_processor = chosen_arch->processor;
+      mips_isa = chosen_arch->isa;
+      if (chosen_arch->cp0_names != NULL)
+	mips_cp0_names = chosen_arch->cp0_names;
+    }
+#endif
+}
+
+void
+parse_mips_dis_option (option, len)
+     const char *option;
+     unsigned int len;
+{
+  unsigned int i, optionlen, vallen;
+  const char *val;
+  const struct mips_abi_choice *chosen_abi;
+  const struct mips_arch_choice *chosen_arch;
+
+  /* Look for the = that delimits the end of the option name.  */
+  for (i = 0; i < len; i++)
+    {
+      if (option[i] == '=')
+	break;
+    }
+  if (i == 0)		/* Invalid option: no name before '='.  */
+    return;
+  if (i == len)		/* Invalid option: no '='.  */
+    return;
+  if (i == (len - 1))	/* Invalid option: no value after '='.  */
+    return;
+
+  optionlen = i;
+  val = option + (optionlen + 1);
+  vallen = len - (optionlen + 1);
+
+  if (strncmp("gpr-names", option, optionlen) == 0
+      && strlen("gpr-names") == optionlen)
+    {
+      chosen_abi = choose_abi_by_name (val, vallen);
+      if (chosen_abi != NULL && chosen_abi->gpr_names != NULL)
+	mips_gpr_names = chosen_abi->gpr_names;
+      return;
+    }
+
+  if (strncmp("fpr-names", option, optionlen) == 0
+      && strlen("fpr-names") == optionlen)
+    {
+      chosen_abi = choose_abi_by_name (val, vallen);
+      if (chosen_abi != NULL && chosen_abi->fpr_names != NULL)
+	mips_fpr_names = chosen_abi->fpr_names;
+      return;
+    }
+
+  if (strncmp("cp0-names", option, optionlen) == 0
+      && strlen("cp0-names") == optionlen)
+    {
+      chosen_arch = choose_arch_by_name (val, vallen);
+      if (chosen_arch != NULL && chosen_arch->cp0_names != NULL)
+	mips_cp0_names = chosen_arch->cp0_names;
+      return;
+    }
+
+  if (strncmp("reg-names", option, optionlen) == 0
+      && strlen("reg-names") == optionlen)
+    {
+      /* We check both ABI and ARCH here unconditionally, so
+	 that "numeric" will do the desirable thing: select
+	 numeric register names for all registers.  Other than
+	 that, a given name probably won't match both.  */
+      chosen_abi = choose_abi_by_name (val, vallen);
+      if (chosen_abi != NULL)
+	{
+	  if (chosen_abi->gpr_names != NULL)
+	    mips_gpr_names = chosen_abi->gpr_names;
+	  if (chosen_abi->fpr_names != NULL)
+	    mips_fpr_names = chosen_abi->fpr_names;
+	}
+      chosen_arch = choose_arch_by_name (val, vallen);
+      if (chosen_arch != NULL)
+	{
+	  if (chosen_arch->cp0_names != NULL)
+	    mips_cp0_names = chosen_arch->cp0_names;
+	}
+      return;
+    }
+
+  /* Invalid option.  */
+}
+
+void
+parse_mips_dis_options (options)
+     const char *options;
+{
+  const char *option_end;
+
+  if (options == NULL)
+    return;
+
+  while (*options != '\0')
+    {
+      /* Skip empty options.  */
+      if (*options == ',')
+	{
+	  options++;
+	  continue;
+	}
+
+      /* We know that *options is neither NUL or a comma.  */
+      option_end = options + 1;
+      while (*option_end != ',' && *option_end != '\0')
+	option_end++;
+
+      parse_mips_dis_option (options, option_end - options);
+
+      /* Go on to the next one.  If option_end points to a comma, it
+	 will be skipped above.  */
+      options = option_end;
+    }
+}
+
 
 /* Print insn arguments for 32/64-bit code.  */
 
@@ -103,7 +478,7 @@ print_insn_arg (d, l, pc, info)
      bfd_vma pc;
      struct disassemble_info *info;
 {
-  int delta;
+  int op, delta;
 
   switch (*d)
     {
@@ -120,13 +495,13 @@ print_insn_arg (d, l, pc, info)
     case 'r':
     case 'v':
       (*info->fprintf_func) (info->stream, "%s",
-			     reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
+			     mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
       break;
 
     case 't':
     case 'w':
       (*info->fprintf_func) (info->stream, "%s",
-			     reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+			     mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
       break;
 
     case 'i':
@@ -173,7 +548,7 @@ print_insn_arg (d, l, pc, info)
 
     case 'd':
       (*info->fprintf_func) (info->stream, "%s",
-			     reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+			     mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
       break;
 
     case 'U':
@@ -182,26 +557,26 @@ print_insn_arg (d, l, pc, info)
 	unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
 	if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
 	  (*info->fprintf_func) (info->stream, "%s",
-				 reg_names[reg]);
+				 mips_gpr_names[reg]);
 	else
 	  {
 	    /* If one is zero use the other.  */
 	    if (reg == 0)
 	      (*info->fprintf_func) (info->stream, "%s",
-				     reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+				     mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
 	    else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
 	      (*info->fprintf_func) (info->stream, "%s",
-				     reg_names[reg]);
+				     mips_gpr_names[reg]);
 	    else /* Bogus, result depends on processor.  */
 	      (*info->fprintf_func) (info->stream, "%s or %s",
-				     reg_names[reg],
-				     reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+				     mips_gpr_names[reg],
+				     mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
 	  }
       }
       break;
 
     case 'z':
-      (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
+      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
       break;
 
     case '<':
@@ -236,34 +611,50 @@ print_insn_arg (d, l, pc, info)
 
     case 'S':
     case 'V':
-      (*info->fprintf_func) (info->stream, "$f%d",
-			     (l >> OP_SH_FS) & OP_MASK_FS);
+      (*info->fprintf_func) (info->stream, "%s",
+			     mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
       break;
 
     case 'T':
     case 'W':
-      (*info->fprintf_func) (info->stream, "$f%d",
-			     (l >> OP_SH_FT) & OP_MASK_FT);
+      (*info->fprintf_func) (info->stream, "%s",
+			     mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
       break;
 
     case 'D':
-      (*info->fprintf_func) (info->stream, "$f%d",
-			     (l >> OP_SH_FD) & OP_MASK_FD);
+      (*info->fprintf_func) (info->stream, "%s",
+			     mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
       break;
 
     case 'R':
-      (*info->fprintf_func) (info->stream, "$f%d",
-			     (l >> OP_SH_FR) & OP_MASK_FR);
+      (*info->fprintf_func) (info->stream, "%s",
+			     mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
       break;
 
     case 'E':
+      /* Coprocessor register for lwcN instructions, et al.
+
+	 Note that there is no load/store cp0 instructions, and
+	 that FPU (cp1) instructions disassemble this field using
+	 'T' format.  Therefore, until we gain understanding of
+	 cp2 register names,
+	 we can simply print the register numbers.  */
       (*info->fprintf_func) (info->stream, "$%d",
 			     (l >> OP_SH_RT) & OP_MASK_RT);
       break;
 
     case 'G':
-      (*info->fprintf_func) (info->stream, "$%d",
-			     (l >> OP_SH_RD) & OP_MASK_RD);
+      /* Coprocessor register for mtcN instructions, et al.
+	 Note that FPU (cp1) instructions disassemble this field using
+	 'S' format.  Therefore, we only need to worry about cp0, cp2,
+	 and cp3.  */
+      op = (l >> OP_SH_OP) & OP_MASK_OP;
+      if (op == OP_OP_COP0)
+        (*info->fprintf_func) (info->stream, "%s",
+			       mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+      else
+        (*info->fprintf_func) (info->stream, "$%d",
+			       (l >> OP_SH_RD) & OP_MASK_RD);
       break;
 
     case 'N':
@@ -352,122 +743,6 @@ print_insn_arg (d, l, pc, info)
     }
 }
 
-/* Figure out the MIPS ISA and CPU based on the machine number.  */
-
-static void
-mips_isa_type (mach, isa, cputype)
-     int mach;
-     int *isa;
-     int *cputype;
-{
-  switch (mach)
-    {
-    case bfd_mach_mips3000:
-      *cputype = CPU_R3000;
-      *isa = ISA_MIPS1;
-      break;
-    case bfd_mach_mips3900:
-      *cputype = CPU_R3900;
-      *isa = ISA_MIPS1;
-      break;
-    case bfd_mach_mips4000:
-      *cputype = CPU_R4000;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4010:
-      *cputype = CPU_R4010;
-      *isa = ISA_MIPS2;
-      break;
-    case bfd_mach_mips4100:
-      *cputype = CPU_VR4100;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4111:
-      *cputype = CPU_R4111;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4120:
-      *cputype = CPU_VR4120;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4300:
-      *cputype = CPU_R4300;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4400:
-      *cputype = CPU_R4400;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4600:
-      *cputype = CPU_R4600;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips4650:
-      *cputype = CPU_R4650;
-      *isa = ISA_MIPS3;
-      break;
-    case bfd_mach_mips5000:
-      *cputype = CPU_R5000;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips5400:
-      *cputype = CPU_VR5400;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips5500:
-      *cputype = CPU_VR5500;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips6000:
-      *cputype = CPU_R6000;
-      *isa = ISA_MIPS2;
-      break;
-    case bfd_mach_mips8000:
-      *cputype = CPU_R8000;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips10000:
-      *cputype = CPU_R10000;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips12000:
-      *cputype = CPU_R12000;
-      *isa = ISA_MIPS4;
-      break;
-    case bfd_mach_mips16:
-      *cputype = CPU_MIPS16;
-      *isa = ISA_MIPS3 | INSN_MIPS16;
-      break;
-    case bfd_mach_mips5:
-      *cputype = CPU_MIPS5;
-      *isa = ISA_MIPS5;
-      break;
-    case bfd_mach_mips_sb1:
-      *cputype = CPU_SB1;
-      *isa = ISA_MIPS64 | INSN_MIPS3D | INSN_SB1;
-      break;
-    case bfd_mach_mipsisa32:
-      *cputype = CPU_MIPS32;
-      /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
-	 Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
-	 _MIPS32 Architecture For Programmers Volume I: Introduction to the
-	 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
-	 page 1.  */
-      *isa = ISA_MIPS32 | INSN_MIPS16;
-      break;
-    case bfd_mach_mipsisa64:
-      *cputype = CPU_MIPS64;
-      /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
-      *isa = ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX;
-      break;
-
-    default:
-      *cputype = CPU_R3000;
-      *isa = ISA_MIPS3;
-      break;
-    }
-}
-
 /* Check if the object uses NewABI conventions.  */
 
 static int
@@ -497,7 +772,6 @@ print_insn_mips (memaddr, word, info)
      struct disassemble_info *info;
 {
   register const struct mips_opcode *op;
-  int target_processor, mips_isa;
   static bfd_boolean init = 0;
   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
 
@@ -523,15 +797,6 @@ print_insn_mips (memaddr, word, info)
       init = 1;
     }
 
-#if ! SYMTAB_AVAILABLE
-  /* This is running out on a target machine, not in a host tool.
-     FIXME: Where does mips_target_info come from?  */
-  target_processor = mips_target_info.processor;
-  mips_isa = mips_target_info.isa;
-#else
-  mips_isa_type (info->mach, &mips_isa, &target_processor);
-#endif
-
   info->bytes_per_chunk = INSNLEN;
   info->display_endian = info->endian;
   info->insn_info_valid = 1;
@@ -551,7 +816,7 @@ print_insn_mips (memaddr, word, info)
 	      register const char *d;
 
 	      /* We always allow to disassemble the jalx instruction.  */
-	      if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor)
+	      if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
 		  && strcmp (op->name, "jalx"))
 		continue;
 
@@ -613,6 +878,9 @@ _print_insn_mips (memaddr, info, endiann
   bfd_byte buffer[INSNLEN];
   int status;
 
+  set_default_mips_dis_options (info);
+  parse_mips_dis_options (info->disassembler_options);
+
 #if 1
   /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
   /* Only a few tools will work this way.  */
@@ -629,18 +897,6 @@ _print_insn_mips (memaddr, info, endiann
     return print_insn_mips16 (memaddr, info);
 #endif
 
-  /* Use mips64_reg_names for new ABI.  */
-  reg_names = mips32_reg_names;
-
-  if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
-    {
-      Elf_Internal_Ehdr *header;
-
-      header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
-      if (is_newabi (header))
-	reg_names = mips64_reg_names;
-    }
-
   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
   if (status == 0)
     {
@@ -879,11 +1135,11 @@ print_mips16_insn_arg (type, op, l, use_
       break;
 
     case '0':
-      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
+      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
       break;
 
     case 'S':
-      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
+      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
       break;
 
     case 'P':
@@ -891,18 +1147,18 @@ print_mips16_insn_arg (type, op, l, use_
       break;
 
     case 'R':
-      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
+      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
       break;
 
     case 'X':
       (*info->fprintf_func) (info->stream, "%s",
-			     mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
-					       & MIPS16OP_MASK_REGR32)]);
+			     mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
+					    & MIPS16OP_MASK_REGR32)]);
       break;
 
     case 'Y':
       (*info->fprintf_func) (info->stream, "%s",
-			     mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
+			     mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
       break;
 
     case '<':
@@ -1185,10 +1441,10 @@ print_mips16_insn_arg (type, op, l, use_
 
 	if (amask > 0 && amask < 5)
 	  {
-	    (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
+	    (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
 	    if (amask > 1)
 	      (*info->fprintf_func) (info->stream, "-%s",
-				     mips32_reg_names[amask + 3]);
+				     mips_gpr_names[amask + 3]);
 	    need_comma = 1;
 	  }
 
@@ -1203,10 +1459,10 @@ print_mips16_insn_arg (type, op, l, use_
 	  {
 	    (*info->fprintf_func) (info->stream, "%s%s",
 				   need_comma ? "," : "",
-				   mips32_reg_names[16]);
+				   mips_gpr_names[16]);
 	    if (smask > 1)
 	      (*info->fprintf_func) (info->stream, "-%s",
-				     mips32_reg_names[smask + 15]);
+				     mips_gpr_names[smask + 15]);
 	    need_comma = 1;
 	  }
 
@@ -1214,7 +1470,7 @@ print_mips16_insn_arg (type, op, l, use_
 	  {
 	    (*info->fprintf_func) (info->stream, "%s%s",
 				   need_comma ? "," : "",
-				   mips32_reg_names[31]);
+				   mips_gpr_names[31]);
 	    need_comma = 1;
 	  }
 
@@ -1236,4 +1492,53 @@ print_mips16_insn_arg (type, op, l, use_
 	 type);
       abort ();
     }
+}
+
+void
+print_mips_disassembler_options (stream)
+     FILE *stream;
+{
+  int i;
+
+  fprintf (stream, _("\n\
+The following MIPS specific disassembler options are supported for use\n\
+with the -M switch (multiple options should be separated by commas):\n"));
+
+  fprintf (stream, _("\n\
+  gpr-names=ABI            Print GPR names according to  specified ABI.\n\
+                           Default: based on binary being disassembled.\n"));
+
+  fprintf (stream, _("\n\
+  fpr-names=ABI            Print FPR names according to specified ABI.\n\
+                           Default: numeric.\n"));
+
+  fprintf (stream, _("\n\
+  cp0-names=ARCH           Print CP0 register names according to\n\
+                           specified architecture.\n\
+                           Default: based on binary being disassembled.\n"));
+
+  fprintf (stream, _("\n\
+  reg-names=ABI            Print GPR and FPR names according to\n\
+                           specified ABI.\n"));
+
+  fprintf (stream, _("\n\
+  reg-names=ARCH           Print CP0 register names according to\n\
+                           specified architecture.\n"));
+
+  fprintf (stream, _("\n\
+  For the options above, the following values are supported for \"ABI\":\n\
+   "));
+  for (i = 0; mips_abi_choices[i].name != NULL; i++)
+    fprintf (stream, " %s", mips_abi_choices[i].name);
+  fprintf (stream, _("\n"));
+
+  fprintf (stream, _("\n\
+  For the options above, The following values are supported for \"ARCH\":\n\
+   "));
+  for (i = 0; mips_arch_choices[i].name != NULL; i++)
+    if (*mips_arch_choices[i].name != '\0')
+      fprintf (stream, " %s", mips_arch_choices[i].name);
+  fprintf (stream, _("\n"));
+
+  fprintf (stream, _("\n"));
 }



More information about the Binutils mailing list