public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] MIPS: Opcode membership proposal
@ 2010-12-18 12:55 Maciej W. Rozycki
  2010-12-20 18:15 ` David Daney
  2011-10-31 12:47 ` Maciej W. Rozycki
  0 siblings, 2 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2010-12-18 12:55 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: binutils

Hi,

 While working on the microMIPS change I have stumbled across the GAS hack 
to support ISA subsetting for the Octeon processors, used to exclude some 
of the CP0 operations.  I decided to implement this properly, based on my 
previous experiments in this area.

 Here's my proposal.  It adds an "exclusions" field to the mips_opcode 
structure.  The new field defines a set of CPU membership flags to exclude 
an opcode for just like they are used with the "membership" field, 
overriding the membership information in the latter field.  Currently only 
CPU_OCTEON has been made to work like this and flags may be added in the 
future as a need arises.  An ISA flag could be handled in a similar way, 
although one is unlikely to be ever needed here.

 The advantage of this approach compared to the current one is not only 
GAS correctly excludes the unsupported opcodes, but `objdump' does as 
well.  And it scales easily, requiring no changes outside opcodes.  
Finally, it makes it clear which opcodes are really unsupported on Octeon 
-- with the current approach it is a bit buried down within code.

 As I've thought adding a trailing zero to initialise the new field 
explicitly throughout the opcode tables would be unnecessary obfuscation 
I've decided to initialise it to a non-zero value for opcodes that require 
it only and allow the source files defining the MIPS opcode tables to have 
uninitialised structure members with the -Wno-missing-field-initializers 
GCC option.  I think it is a good compromise -- these tables are validated 
at run time too and the files contain no other code.

 I have decided to retain the CP pinfo flag defined with the change that 
introduced the current Octeon opcode exclusion code.  The flag is not used 
anymore, but the effort previously taken to annotate the relevant opcodes 
may be useful for something else in the future.

 No regressions for mips-sde-elf nor mips-linux-gnu.  Applies on top of 
the microMIPS change.

2010-12-18  Maciej W. Rozycki  <macro@codesourcery.com>

	include/opcode/
	* mips.h (mips_opcode): Add the exclusions field.
	(OPCODE_IS_MEMBER): Check exclusions for exceptions.

	opcodes/
	* micromips-opc.c (micromips_opcodes): Update comment.
	* mips-opc.c (mips_builtin_opcodes): Likewise.  Mark coprocessor
	instructions for IOCT as appropriate.
	* configure.in: Substitute NO_WFIELD with the result of a check
	for the -Wno-missing-field-initializers GCC option.
	* Makefile.am (NO_WFIELD): New variable.
	(mips-opc.lo): Pass $(NO_WFIELD) to compilation.
	(mips16-opc.lo): Likewise.
	(micromips-opc.lo): Likewise.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* Makefile.in: Regenerate.

	gas/
	* config/tc-mips.c (NO_ISA_COP, COP_INSN): Remove macros.
	(is_opcode_valid): Remove coprocessor instruction exclusions.
	(macro): Likewise.

 OK?

  Maciej

binutils-opcode-exclude.diff
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2010-12-16 11:15:20.000000000 +0000
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2010-12-16 11:15:22.000000000 +0000
@@ -337,6 +337,9 @@ struct mips_opcode
   /* A collection of bits describing the instruction sets of which this
      instruction or macro is a member. */
   unsigned long membership;
+  /* A collection of bits describing the instruction sets of which this
+     instruction or macro is not a member.  */
+  unsigned long exclusions;
 };
 
 /* These are the characters which may appear in the args field of an
@@ -795,37 +798,38 @@ static const unsigned int mips_isa_table
    ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
    test, or zero if no CPU specific ISA test is desired.  */
 
-#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
-    (((isa & INSN_ISA_MASK) != 0                                        \
-      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
-      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
-           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
-     || ((isa & ~INSN_ISA_MASK)                                         \
-          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
-     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
-     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
-     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
-     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
-	  || cpu == CPU_R16000)						\
-	 && ((insn)->membership & INSN_10000) != 0)			\
-     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
-     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
-     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
-     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
-     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
-     || (cpu == CPU_LOONGSON_2E                                         \
-         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
-     || (cpu == CPU_LOONGSON_2F                                         \
-         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
-     || (cpu == CPU_LOONGSON_3A                                         \
-         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
-     || (cpu == CPU_OCTEON						\
-	 && ((insn)->membership & INSN_OCTEON) != 0)			\
-     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
-     || 0)	/* Please keep this term for easier source merging.  */
+#define OPCODE_IS_MEMBER(insn, isa, cpu)				    \
+    ((((isa & INSN_ISA_MASK) != 0					    \
+       && ((insn)->membership & INSN_ISA_MASK) != 0			    \
+       && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>		    \
+	    (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)	    \
+      || ((isa & ~INSN_ISA_MASK)					    \
+	   & ((insn)->membership & ~INSN_ISA_MASK)) != 0		    \
+      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	    \
+      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	    \
+      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	    \
+      || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	    \
+	   || cpu == CPU_R16000)					    \
+	  && ((insn)->membership & INSN_10000) != 0)			    \
+      || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	    \
+      || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	    \
+      || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	    \
+      || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	    \
+      || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	    \
+      || (cpu == CPU_LOONGSON_2E					    \
+	  && ((insn)->membership & INSN_LOONGSON_2E) != 0)		    \
+      || (cpu == CPU_LOONGSON_2F					    \
+	  && ((insn)->membership & INSN_LOONGSON_2F) != 0)		    \
+      || (cpu == CPU_LOONGSON_3A					    \
+	  && ((insn)->membership & INSN_LOONGSON_3A) != 0)		    \
+      || (cpu == CPU_OCTEON && ((insn)->membership & INSN_OCTEON) != 0)    \
+      || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)	    \
+      || 0)	/* Please keep this term for easier source merging.  */	    \
+     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	    \
+	 && 1))	/* Please keep this term for easier source merging.  */
 
 /* This is a list of macro expanded instructions.
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.am
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.am	2010-12-16 11:15:18.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.am	2010-12-16 11:15:22.000000000 +0000
@@ -11,6 +11,7 @@ BFDDIR = $(srcdir)/../bfd
 
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
+NO_WFIELD = @NO_WFIELD@
 AM_CFLAGS = $(WARN_CFLAGS)
 
 COMPILE_FOR_BUILD = $(CC_FOR_BUILD) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -498,6 +499,15 @@ $(srcdir)/ia64-asmtab.c: @MAINT@ $(ia64_
 
 ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.in	2010-12-16 11:15:18.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.in	2010-12-16 11:15:22.000000000 +0000
@@ -54,6 +54,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../b
 	$(top_srcdir)/../config/override.m4 \
 	$(top_srcdir)/../config/po.m4 \
 	$(top_srcdir)/../config/progtest.m4 \
+	$(top_srcdir)/../config/warnings.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
 	$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
 	$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.in
@@ -195,6 +196,7 @@ MSGMERGE = @MSGMERGE@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NO_WERROR = @NO_WERROR@
+NO_WFIELD = @NO_WFIELD@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OTOOL = @OTOOL@
@@ -801,6 +803,7 @@ libopcodes.la: $(libopcodes_la_OBJECTS) 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mep-ibld.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mep-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/microblaze-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/micromips-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mips-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mips-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mips16-opc.Plo@am__quote@
@@ -1333,6 +1336,15 @@ $(srcdir)/ia64-asmtab.c: @MAINT@ $(ia64_
 
 ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/aclocal.m4
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/aclocal.m4	2010-12-14 01:27:30.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/aclocal.m4	2010-12-16 11:15:22.000000000 +0000
@@ -978,6 +978,7 @@ m4_include([../config/nls.m4])
 m4_include([../config/override.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
+m4_include([../config/warnings.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
Index: binutils-fsf-trunk-quilt/opcodes/configure
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure	2010-12-16 11:15:18.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/configure	2010-12-16 11:15:22.000000000 +0000
@@ -640,6 +640,7 @@ INSTALL_LIBBFD_TRUE
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+NO_WFIELD
 NO_WERROR
 WARN_CFLAGS
 OTOOL64
@@ -11142,7 +11143,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11145 "configure"
+#line 11146 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11248,7 +11249,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11251 "configure"
+#line 11252 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11569,6 +11570,45 @@ fi
 
 
 
+NO_WFIELD=
+save_CFLAGS="$CFLAGS"
+for option in -Wno-missing-field-initializers; do
+  as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
+$as_echo_n "checking whether $CC supports $option... " >&6; }
+if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  CFLAGS="$option"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_acx_Woption=yes"
+else
+  eval "$as_acx_Woption=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+eval ac_res=\$$as_acx_Woption
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
+  NO_WFIELD="$NO_WFIELD${NO_WFIELD:+ }$option"
+fi
+  done
+CFLAGS="$save_CFLAGS"
+
 
 ac_config_headers="$ac_config_headers config.h:config.in"
 
Index: binutils-fsf-trunk-quilt/opcodes/configure.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure.in	2010-12-16 11:15:18.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/configure.in	2010-12-16 11:15:22.000000000 +0000
@@ -42,6 +42,7 @@ AC_ARG_ENABLE(targets,
 esac])dnl
 
 AM_BINUTILS_WARNINGS
+ACX_PROG_CC_WARNING_OPTS([-Wno-missing-field-initializers], [NO_WFIELD])
 
 AC_CONFIG_HEADERS(config.h:config.in)
 
Index: binutils-fsf-trunk-quilt/opcodes/micromips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/micromips-opc.c	2010-12-16 11:15:20.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/micromips-opc.c	2010-12-16 11:15:22.000000000 +0000
@@ -102,7 +102,7 @@ const struct mips_opcode micromips_opcod
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership */
+/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership,	[exclusions] */
 {"pref",    "k,~(b)",	0x60002000, 0xfc00f000,	RD_b,			0,		I1	},
 {"pref",    "k,o(b)",	0,    (int) M_PREF_OB,	INSN_MACRO,		0,		I1	},
 {"prefx",   "h,t(b)",	0x540001a0, 0xfc0007ff,	RD_b|RD_t|FP_S,		0,		I1	},
Index: binutils-fsf-trunk-quilt/opcodes/mips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips-opc.c	2010-12-16 11:15:20.000000000 +0000
+++ binutils-fsf-trunk-quilt/opcodes/mips-opc.c	2010-12-16 11:15:22.000000000 +0000
@@ -185,7 +185,7 @@ const struct mips_opcode mips_builtin_op
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership */
+/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership,	[exclusions] */
 {"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	0,		I4_32|G3	},
 {"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S,		0,		I4_33	},
 {"nop",     "",         0x00000000, 0xffffffff, 0,              	INSN2_ALIAS,	I1      }, /* sll */
@@ -522,27 +522,27 @@ const struct mips_opcode mips_builtin_op
 {"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3_33	},
 {"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
 {"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
-{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1,		IOCT	},
 {"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 {"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 /* cfc2 is at the bottom of the table.  */
 /* cfc3 is at the bottom of the table.  */
 {"cftc1",   "d,E",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
 {"cftc1",   "d,T",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
-{"cftc2",   "d,E",	0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"cftc2",   "d,E",	0x41000025, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"cins32",  "t,r,+p,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"cins",    "t,r,+P,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	}, /* cins32 */
 {"cins",    "t,r,+p,+s",0x70000032, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"clo",     "U,s",      0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
 {"clz",     "U,s",      0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
-{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
 {"ctc1",    "t,G",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 {"ctc1",    "t,S",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 /* ctc2 is at the bottom of the table.  */
 /* ctc3 is at the bottom of the table.  */
 {"cttc1",   "t,g",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
 {"cttc1",   "t,S",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
-{"cttc2",   "t,g",	0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC,	0,		MT32	},
+{"cttc2",   "t,g",	0x41800025, 0xffe007ff,	TRAP|COD|RD_t|WR_CC,	0,		MT32,		IOCT	},
 {"cvt.d.l", "D,S",	0x46a00021, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I3_33	},
 {"cvt.d.s", "D,S",	0x46000021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
 {"cvt.d.w", "D,S",	0x46800021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
@@ -587,8 +587,8 @@ const struct mips_opcode mips_builtin_op
 {"ddivu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
 {"ddivu",   "d,v,t",	0,    (int) M_DDIVU_3,	INSN_MACRO,		0,		I3	},
 {"ddivu",   "d,v,I",	0,    (int) M_DDIVU_3I,	INSN_MACRO,		0,		I3	},
-{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		0,		I65	},
 {"dins",    "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
 {"dinsm",   "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
@@ -623,14 +623,14 @@ const struct mips_opcode mips_builtin_op
 {"dmaccu",  "d,s,t",	0x00000069, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmaccus", "d,s,t",	0x00000469, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmadd16", "s,t",      0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO,       0,		N411    },
-{"dmfc0",   "t,G",	0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,		0,		I3|IOCT	},
-{"dmfc0",   "t,+D",     0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
-{"dmfc0",   "t,G,H",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
+{"dmfc0",   "t,G",	0x40200000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I3	},
+{"dmfc0",   "t,+D",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
+{"dmfc0",   "t,G,H",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
 {"dmt",     "",		0x41600bc1, 0xffffffff, TRAP,			0,		MT32	},
 {"dmt",     "t",	0x41600bc1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	0,		I3|IOCT	},
-{"dmtc0",   "t,+D",     0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
-{"dmtc0",   "t,G,H",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
+{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I3	},
+{"dmtc0",   "t,+D",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
+{"dmtc0",   "t,G,H",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
 {"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,	0,		I3	},
 {"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,		I3      },
 {"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,	0,		I3	},
@@ -702,8 +702,8 @@ const struct mips_opcode mips_builtin_op
 {"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		0,		I3	},
 {"dvpe",    "",		0x41600001, 0xffffffff, TRAP,			0,		MT32	},
 {"dvpe",    "t",	0x41600001, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"emt",     "",		0x41600be1, 0xffffffff, TRAP,			0,		MT32	},
 {"emt",     "t",	0x41600be1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
 {"eret",    "",         0x42000018, 0xffffffff, 0,      		0,		I3_32	},
@@ -768,10 +768,10 @@ const struct mips_opcode mips_builtin_op
 {"l.d",     "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	}, /* ldc1 */
 {"l.d",     "T,o(b)",	0,    (int) M_L_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"l.d",     "T,A(b)",	0,    (int) M_L_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
-{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2	},
-{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2	},
+{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT	},
+{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2,		IOCT	},
+{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT	},
+{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2,		IOCT	},
 {"ldl",	    "t,o(b)",	0x68000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
 {"ldl",	    "t,A(b)",	0,    (int) M_LDL_AB,	INSN_MACRO,		0,		I3	},
 {"ldr",	    "t,o(b)",	0x6c000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
@@ -794,18 +794,18 @@ const struct mips_opcode mips_builtin_op
 {"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I5_33|N55},
 {"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		0,		I1	},
-{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1	},
+{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"lwc1",    "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "E,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"lwc1",    "E,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"l.s",     "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	}, /* lwc1 */
 {"l.s",     "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1	},
-{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1	},
+{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1,		IOCT	},
+{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"lwl",     "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lwl",     "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I1	},
 {"lcache",  "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I2	}, /* same */
@@ -868,20 +868,20 @@ const struct mips_opcode mips_builtin_op
 {"mftc0",   "d,E,H",	0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
 {"mftc1",   "d,T",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
 {"mftc1",   "d,E",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
-{"mftc2",   "d,E",	0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mftc2",   "d,E",	0x41000024, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"mftdsp",  "d",	0x41100021, 0xffff07ff, TRAP|WR_d,		0,		MT32	},
 {"mftgpr",  "d,t",	0x41000020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mfthc1",  "d,T",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
 {"mfthc1",  "d,E",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
-{"mfthc2",  "d,E",	0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mfthc2",  "d,E",	0x41000034, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"mfthi",   "d",	0x41010021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mfthi",   "d,*",	0x41010021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d",	0x41000021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d,*",	0x41000021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftr",    "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d,		0,		MT32	},
-{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1|IOCT	},
-{"mfc0",    "t,+D",     0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
-{"mfc0",    "t,G,H",    0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
+{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"mfc0",    "t,+D",0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
+{"mfc0",    "t,G,H",	0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
 {"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
@@ -960,9 +960,9 @@ const struct mips_opcode mips_builtin_op
 {"msubu",   "7,s,t",	0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D32	},
 {"mtpc",    "t,P",	0x4080c801, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
 {"mtps",    "t,P",	0x4080c800, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
-{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1|IOCT	},
-{"mtc0",    "t,+D",     0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
-{"mtc0",    "t,G,H",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
+{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1	},
+{"mtc0",    "t,+D",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
+{"mtc0",    "t,G,H",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
 {"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
@@ -988,14 +988,14 @@ const struct mips_opcode mips_builtin_op
 {"mttc0",   "t,G,H",	0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
 {"mttc1",   "t,S",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
 {"mttc1",   "t,G",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
-{"mttc2",   "t,g",	0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mttc2",   "t,g",	0x41800024, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT	},
 {"mttacx",  "t",	0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttacx",  "t,&",	0x41801021, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttdsp",  "t",	0x41808021, 0xffe0ffff, TRAP|RD_t,		0,		MT32	},
 {"mttgpr",  "t,d",	0x41800020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mtthc1",  "t,S",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
 {"mtthc1",  "t,G",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
-{"mtthc2",  "t,g",	0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mtthc2",  "t,g",	0x41800034, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT	},
 {"mtthi",   "t",	0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mtthi",   "t,&",	0x41800821, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttlo",   "t",	0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
@@ -1198,10 +1198,10 @@ const struct mips_opcode mips_builtin_op
 {"sdc1",    "E,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"sdc1",    "T,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
 {"sdc1",    "E,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
-{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000, SM|RD_C2|RD_b,		0,		I2	},
-{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2	},
-{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000, SM|RD_C3|RD_b,		0,		I2	},
-{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2	},
+{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I2,		IOCT	},
+{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2,		IOCT	},
+{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I2,		IOCT	},
+{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2,		IOCT	},
 {"s.d",     "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"s.d",     "T,o(b)",	0,    (int) M_S_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"s.d",     "T,A(b)",	0,    (int) M_S_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
@@ -1323,18 +1323,18 @@ const struct mips_opcode mips_builtin_op
 {"swapw",   "t,b",	0x70000014, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapwu",  "t,b",	0x70000015, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapd",   "t,b",	0x70000016, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
-{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1	},
-{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1	},
+{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1,		IOCT	},
+{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"swc1",    "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "E,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"swc1",    "E,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"s.s",     "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	}, /* swc1 */
 {"s.s",     "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1	},
-{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1	},
-{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1	},
-{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1	},
+{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1,		IOCT	},
+{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1,		IOCT	},
+{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1,		IOCT	},
+{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"swl",     "t,o(b)",	0xa8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"swl",     "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I1	},
 {"scache",  "t,o(b)",	0xa8000000, 0xfc000000,	RD_t|RD_b,		0,		I2	}, /* same */
@@ -1511,47 +1511,47 @@ const struct mips_opcode mips_builtin_op
 
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
-{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT	},
+{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT	},
+{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT	},
+{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT	},
+{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT	},
+{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
 {"dmfc2",   "t,i",	0x48200000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		IOCT	},
-{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3	},
-{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64	},
+{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3,		IOCT	},
+{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64,		IOCT	},
 {"dmtc2",   "t,i",	0x48a00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		IOCT	},
-{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3	},
-{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64	},
-{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32	},
-{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1	},
-{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32	},
-{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
+{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3,		IOCT	},
+{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64,		IOCT	},
+{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT	},
+{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32,		IOCT	},
+{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1,		IOCT	},
+{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32,		IOCT	},
+{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
+{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
+{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
 
 /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X 
    instructions, so they are here for the latters to take precedence.  */
-{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
-{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 	0,		I3	},
-{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC,	0,		I3	},
-{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"mfc3",    "t,G,H",    0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 	0,		I32     },
-{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1	},
-{"mtc3",    "t,G,H",    0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   0,		I32     },
+{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT	},
+{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
+{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I3,		IOCT	},
+{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I3,		IOCT	},
+{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT	},
+{"mfc3",    "t,G,H",	0x4c000000, 0xffe007f8,	LCD|WR_t|RD_C3,		0,		I32,		IOCT	},
+{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1,		IOCT	},
+{"mtc3",    "t,G,H",	0x4c800000, 0xffe007f8,	COD|RD_t|WR_C3|WR_CC,	0,		I32,		IOCT	},
 
   /* Conflicts with the 4650's "mul" instruction.  Nobody's using the
      4010 any more, so move this insn out of the way.  If the object
@@ -1841,10 +1841,10 @@ const struct mips_opcode mips_builtin_op
 {"dpsqx_s.w.ph", "7,s,t", 0x7c000670, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 {"dpsqx_sa.w.ph", "7,s,t", 0x7c0006f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 /* Move bc0* after mftr and mttr to avoid opcode collision.  */
-{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
 /* ST Microelectronics Loongson-2E and -2F.  */
 {"mult.g",	"d,s,t",	0x7c000018,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2E	},
 {"mult.g",	"d,s,t",	0x70000010,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2F	},
@@ -1992,14 +1992,14 @@ const struct mips_opcode mips_builtin_op
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
    disassembler recognizes more specific versions first.  */
-{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1	},
+{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
 {"c1",      "C",	0x46000000, 0xfe000000,	FP_S,			0,		I1	},
-{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1	},
-{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1	},
-{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1	},
+{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
+{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
+{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1,		IOCT	},
 {"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1	},
-{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1	}
+{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1,		IOCT	},
+{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1,		IOCT	},
 };
 
 #define MIPS_NUM_OPCODES \
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2010-12-16 11:15:21.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2010-12-16 11:15:22.000000000 +0000
@@ -482,11 +482,6 @@ static int mips_32bitmode = 0;
 /* True if CPU has seq/sne and seqi/snei instructions.  */
 #define CPU_HAS_SEQ(CPU)	((CPU) == CPU_OCTEON)
 
-/* True if CPU does not implement the all the coprocessor insns.  For these
-   CPUs only those COP insns are accepted that are explicitly marked to be
-   available on the CPU.  ISA membership for COP insns is ignored.  */
-#define NO_ISA_COP(CPU)		((CPU) == CPU_OCTEON)
-
 /* True if mflo and mfhi can be immediately followed by instructions
    which write to the HI and LO registers.
 
@@ -555,15 +550,6 @@ static int mips_32bitmode = 0;
 #define MF_HILO_INSN(PINFO) \
   ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
 
-/* Returns true for a (non floating-point) coprocessor instruction.  Reading
-   or writing the condition code is only possible on the coprocessors and
-   these insns are not marked with INSN_COP.  Thus for these insns use the
-   condition-code flags.  */
-#define COP_INSN(PINFO)							\
-  (PINFO != INSN_MACRO							\
-   && ((PINFO) & (FP_S | FP_D)) == 0					\
-   && ((PINFO) & (INSN_COP | INSN_READ_COND_CODE | INSN_WRITE_COND_CODE)))
-
 /* Whether code compression (either of the MIPS16 or the microMIPS ASEs)
    has been selected.  This implies, in particular, that addresses of text
    labels have their LSB set.  */
@@ -2102,12 +2088,6 @@ is_opcode_valid (const struct mips_opcod
   if (mips_opts.ase_mcu)
     isa |= INSN_MCU;
 
-  /* Don't accept instructions based on the ISA if the CPU does not implement
-     all the coprocessor insns. */
-  if (NO_ISA_COP (mips_opts.arch)
-      && COP_INSN (mo->pinfo))
-    isa = 0;
-
   if (!OPCODE_IS_MEMBER (mo, isa, mips_opts.arch))
     return FALSE;
 
@@ -7860,15 +7840,6 @@ macro (struct mips_cl_insn *ip)
       tempreg = AT;
       used_at = 1;
     ld_noat:
-      if (coproc
-	  && NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & (INSN2_M_FP_S | INSN2_M_FP_D)) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       if (offset_expr.X_op != O_constant
 	  && offset_expr.X_op != O_symbol)
 	{
@@ -8767,14 +8738,6 @@ macro (struct mips_cl_insn *ip)
       s = "c3";
     copz:
       gas_assert (!mips_opts.micromips);
-      if (NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       /* For now we just do C (same as Cz).  The parameter will be
          stored in insn_opcode by mips_ip.  */
       macro_build (NULL, s, "C", ip->insn_opcode);

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2010-12-18 12:55 [PATCH] MIPS: Opcode membership proposal Maciej W. Rozycki
@ 2010-12-20 18:15 ` David Daney
  2010-12-20 18:33   ` Andrew Pinski
  2011-10-31 12:47 ` Maciej W. Rozycki
  1 sibling, 1 reply; 14+ messages in thread
From: David Daney @ 2010-12-20 18:15 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Richard Sandiford, binutils, Pinski, Andrew

On 12/18/2010 03:42 AM, Maciej W. Rozycki wrote:
> Hi,
>
>   While working on the microMIPS change I have stumbled across the GAS hack
> to support ISA subsetting for the Octeon processors, used to exclude some
> of the CP0 operations.  I decided to implement this properly, based on my
> previous experiments in this area.
>
>   Here's my proposal.  It adds an "exclusions" field to the mips_opcode
> structure.  The new field defines a set of CPU membership flags to exclude
> an opcode for just like they are used with the "membership" field,
> overriding the membership information in the latter field.  Currently only
> CPU_OCTEON has been made to work like this and flags may be added in the
> future as a need arises.  An ISA flag could be handled in a similar way,
> although one is unlikely to be ever needed here.
>
>   The advantage of this approach compared to the current one is not only
> GAS correctly excludes the unsupported opcodes, but `objdump' does as
> well.  And it scales easily, requiring no changes outside opcodes.
> Finally, it makes it clear which opcodes are really unsupported on Octeon
> -- with the current approach it is a bit buried down within code.
>
>   As I've thought adding a trailing zero to initialise the new field
> explicitly throughout the opcode tables would be unnecessary obfuscation
> I've decided to initialise it to a non-zero value for opcodes that require
> it only and allow the source files defining the MIPS opcode tables to have
> uninitialised structure members with the -Wno-missing-field-initializers
> GCC option.  I think it is a good compromise -- these tables are validated
> at run time too and the files contain no other code.
>
>   I have decided to retain the CP pinfo flag defined with the change that
> introduced the current Octeon opcode exclusion code.  The flag is not used
> anymore, but the effort previously taken to annotate the relevant opcodes
> may be useful for something else in the future.
>
>   No regressions for mips-sde-elf nor mips-linux-gnu.  Applies on top of
> the microMIPS change.
>

For the record, this seems like a sane approach.  I have not gone 
through the patch with a fine toothed comb, but it seems like an 
improvement over the current approach.

Andrew Pinski may want to take a look, but from my point of view, if 
Richard likes it, I think it should be committed.

Thanks,
David Daney

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2010-12-20 18:15 ` David Daney
@ 2010-12-20 18:33   ` Andrew Pinski
  0 siblings, 0 replies; 14+ messages in thread
From: Andrew Pinski @ 2010-12-20 18:33 UTC (permalink / raw)
  To: David Daney; +Cc: Maciej W. Rozycki, Richard Sandiford, binutils

On Mon, 2010-12-20 at 09:40 -0800, David Daney wrote:
> 
> For the record, this seems like a sane approach.  I have not gone 
> through the patch with a fine toothed comb, but it seems like an 
> improvement over the current approach.

This does indead sound like a good sane approach in cleaning up this
area.


> 
> Andrew Pinski may want to take a look, but from my point of view, if 
> Richard likes it, I think it should be committed.


The patch also looks sane but I have not gone with a fine toothed comb
either.

Thanks,

Andrew Pinski

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2010-12-18 12:55 [PATCH] MIPS: Opcode membership proposal Maciej W. Rozycki
  2010-12-20 18:15 ` David Daney
@ 2011-10-31 12:47 ` Maciej W. Rozycki
  2011-11-17 18:45   ` Richard Sandiford
  1 sibling, 1 reply; 14+ messages in thread
From: Maciej W. Rozycki @ 2011-10-31 12:47 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: David Daney, Andrew Pinski, binutils

Hi Richard,

On Sat, 18 Dec 2010, Maciej W. Rozycki wrote:

>  While working on the microMIPS change I have stumbled across the GAS hack 
> to support ISA subsetting for the Octeon processors, used to exclude some 
> of the CP0 operations.  I decided to implement this properly, based on my 
> previous experiments in this area.
> 
>  Here's my proposal.  It adds an "exclusions" field to the mips_opcode 
> structure.  The new field defines a set of CPU membership flags to exclude 
> an opcode for just like they are used with the "membership" field, 
> overriding the membership information in the latter field.  Currently only 
> CPU_OCTEON has been made to work like this and flags may be added in the 
> future as a need arises.  An ISA flag could be handled in a similar way, 
> although one is unlikely to be ever needed here.
> 
>  The advantage of this approach compared to the current one is not only 
> GAS correctly excludes the unsupported opcodes, but `objdump' does as 
> well.  And it scales easily, requiring no changes outside opcodes.  
> Finally, it makes it clear which opcodes are really unsupported on Octeon 
> -- with the current approach it is a bit buried down within code.
> 
>  As I've thought adding a trailing zero to initialise the new field 
> explicitly throughout the opcode tables would be unnecessary obfuscation 
> I've decided to initialise it to a non-zero value for opcodes that require 
> it only and allow the source files defining the MIPS opcode tables to have 
> uninitialised structure members with the -Wno-missing-field-initializers 
> GCC option.  I think it is a good compromise -- these tables are validated 
> at run time too and the files contain no other code.
> 
>  I have decided to retain the CP pinfo flag defined with the change that 
> introduced the current Octeon opcode exclusion code.  The flag is not used 
> anymore, but the effort previously taken to annotate the relevant opcodes 
> may be useful for something else in the future.
> 
>  No regressions for mips-sde-elf nor mips-linux-gnu.  Applies on top of 
> the microMIPS change.

 I have received positive feedback from David and Andrew, but I haven't 
heard from you.  What do you think about this change?  I have trivially 
regenerated it and regression re-tested as above.

2011-10-31  Maciej W. Rozycki  <macro@codesourcery.com>

	include/opcode/
	* mips.h (mips_opcode): Add the exclusions field.
	(OPCODE_IS_MEMBER): Check exclusions for exceptions.

	opcodes/
	* micromips-opc.c (micromips_opcodes): Update comment.
	* mips-opc.c (mips_builtin_opcodes): Likewise.  Mark coprocessor
	instructions for IOCT as appropriate.
	* configure.in: Substitute NO_WFIELD with the result of a check
	for the -Wno-missing-field-initializers GCC option.
	* Makefile.am (NO_WFIELD): New variable.
	(mips-opc.lo): Pass $(NO_WFIELD) to compilation.
	(mips16-opc.lo): Likewise.
	(micromips-opc.lo): Likewise.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* Makefile.in: Regenerate.

	gas/
	* config/tc-mips.c (NO_ISA_COP, COP_INSN): Remove macros.
	(is_opcode_valid): Remove coprocessor instruction exclusions.
	(macro): Likewise.

  Maciej

binutils-opcode-exclude.diff
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2011-10-24 23:03:24.695863796 +0100
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2011-10-24 23:03:27.865865912 +0100
@@ -353,6 +353,9 @@ struct mips_opcode
   /* A collection of bits describing the instruction sets of which this
      instruction or macro is a member. */
   unsigned long membership;
+  /* A collection of bits describing the instruction sets of which this
+     instruction or macro is not a member.  */
+  unsigned long exclusions;
 };
 
 /* These are the characters which may appear in the args field of an
@@ -830,37 +833,38 @@ static const unsigned int mips_isa_table
    ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
    test, or zero if no CPU specific ISA test is desired.  */
 
-#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
-    (((isa & INSN_ISA_MASK) != 0                                        \
-      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
-      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
-           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
-     || ((isa & ~INSN_ISA_MASK)                                         \
-          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
-     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
-     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
-     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
-     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
-	  || cpu == CPU_R16000)						\
-	 && ((insn)->membership & INSN_10000) != 0)			\
-     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
-     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
-     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
-     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
-     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
-     || (cpu == CPU_LOONGSON_2E                                         \
-         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
-     || (cpu == CPU_LOONGSON_2F                                         \
-         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
-     || (cpu == CPU_LOONGSON_3A                                         \
-         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
-     || (cpu == CPU_OCTEON						\
-	 && ((insn)->membership & INSN_OCTEON) != 0)			\
-     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
-     || 0)	/* Please keep this term for easier source merging.  */
+#define OPCODE_IS_MEMBER(insn, isa, cpu)				    \
+    ((((isa & INSN_ISA_MASK) != 0					    \
+       && ((insn)->membership & INSN_ISA_MASK) != 0			    \
+       && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>		    \
+	    (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)	    \
+      || ((isa & ~INSN_ISA_MASK)					    \
+	   & ((insn)->membership & ~INSN_ISA_MASK)) != 0		    \
+      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	    \
+      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	    \
+      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	    \
+      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	    \
+      || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	    \
+	   || cpu == CPU_R16000)					    \
+	  && ((insn)->membership & INSN_10000) != 0)			    \
+      || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	    \
+      || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	    \
+      || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	    \
+      || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	    \
+      || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	    \
+      || (cpu == CPU_LOONGSON_2E					    \
+	  && ((insn)->membership & INSN_LOONGSON_2E) != 0)		    \
+      || (cpu == CPU_LOONGSON_2F					    \
+	  && ((insn)->membership & INSN_LOONGSON_2F) != 0)		    \
+      || (cpu == CPU_LOONGSON_3A					    \
+	  && ((insn)->membership & INSN_LOONGSON_3A) != 0)		    \
+      || (cpu == CPU_OCTEON && ((insn)->membership & INSN_OCTEON) != 0)    \
+      || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)	    \
+      || 0)	/* Please keep this term for easier source merging.  */	    \
+     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	    \
+	 && 1))	/* Please keep this term for easier source merging.  */
 
 /* This is a list of macro expanded instructions.
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.am
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.am	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.am	2011-10-24 23:03:27.865865912 +0100
@@ -11,6 +11,7 @@ BFDDIR = $(srcdir)/../bfd
 
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
+NO_WFIELD = @NO_WFIELD@
 AM_CFLAGS = $(WARN_CFLAGS)
 
 COMPILE_FOR_BUILD = $(CC_FOR_BUILD) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -502,6 +503,15 @@ $(srcdir)/ia64-asmtab.c: @MAINT@ $(ia64_
 
 ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.in	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.in	2011-10-24 23:03:27.865865912 +0100
@@ -54,6 +54,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../b
 	$(top_srcdir)/../config/override.m4 \
 	$(top_srcdir)/../config/po.m4 \
 	$(top_srcdir)/../config/progtest.m4 \
+	$(top_srcdir)/../config/warnings.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
 	$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
 	$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.in
@@ -195,6 +196,7 @@ MSGMERGE = @MSGMERGE@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NO_WERROR = @NO_WERROR@
+NO_WFIELD = @NO_WFIELD@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OTOOL = @OTOOL@
@@ -1342,6 +1344,15 @@ $(srcdir)/ia64-asmtab.c: @MAINT@ $(ia64_
 
 ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WFIELD) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/aclocal.m4
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/aclocal.m4	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/aclocal.m4	2011-10-24 23:03:27.865865912 +0100
@@ -978,6 +978,7 @@ m4_include([../config/nls.m4])
 m4_include([../config/override.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
+m4_include([../config/warnings.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
Index: binutils-fsf-trunk-quilt/opcodes/configure
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/configure	2011-10-24 23:03:27.865865912 +0100
@@ -640,6 +640,7 @@ INSTALL_LIBBFD_TRUE
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+NO_WFIELD
 NO_WERROR
 WARN_CFLAGS
 OTOOL64
@@ -11134,7 +11135,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11137 "configure"
+#line 11138 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11240,7 +11241,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11243 "configure"
+#line 11244 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11561,6 +11562,45 @@ fi
 
 
 
+NO_WFIELD=
+save_CFLAGS="$CFLAGS"
+for option in -Wno-missing-field-initializers; do
+  as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
+$as_echo_n "checking whether $CC supports $option... " >&6; }
+if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  CFLAGS="$option"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_acx_Woption=yes"
+else
+  eval "$as_acx_Woption=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+eval ac_res=\$$as_acx_Woption
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
+  NO_WFIELD="$NO_WFIELD${NO_WFIELD:+ }$option"
+fi
+  done
+CFLAGS="$save_CFLAGS"
+
 
 ac_config_headers="$ac_config_headers config.h:config.in"
 
Index: binutils-fsf-trunk-quilt/opcodes/configure.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure.in	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/configure.in	2011-10-24 23:03:27.865865912 +0100
@@ -42,6 +42,7 @@ AC_ARG_ENABLE(targets,
 esac])dnl
 
 AM_BINUTILS_WARNINGS
+ACX_PROG_CC_WARNING_OPTS([-Wno-missing-field-initializers], [NO_WFIELD])
 
 AC_CONFIG_HEADERS(config.h:config.in)
 
Index: binutils-fsf-trunk-quilt/opcodes/micromips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/micromips-opc.c	2011-10-24 23:03:24.695863796 +0100
+++ binutils-fsf-trunk-quilt/opcodes/micromips-opc.c	2011-10-24 23:03:27.865865912 +0100
@@ -115,7 +115,7 @@ const struct mips_opcode micromips_opcod
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership */
+/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership,	[exclusions] */
 {"pref",    "k,~(b)",	0x60002000, 0xfc00f000,	RD_b,			0,		I1	},
 {"pref",    "k,o(b)",	0,    (int) M_PREF_OB,	INSN_MACRO,		0,		I1	},
 {"pref",    "k,A(b)",	0,    (int) M_PREF_AB,	INSN_MACRO,		0,		I1	},
Index: binutils-fsf-trunk-quilt/opcodes/mips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips-opc.c	2011-10-24 22:15:54.335460119 +0100
+++ binutils-fsf-trunk-quilt/opcodes/mips-opc.c	2011-10-24 23:03:27.865865912 +0100
@@ -194,7 +194,7 @@ const struct mips_opcode mips_builtin_op
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership */
+/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership,	[exclusions] */
 {"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	0,		I4_32|G3	},
 {"pref",    "k,A(b)",	0,    (int) M_PREF_AB,	INSN_MACRO,		0,		I4_32|G3	},
 {"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S,		0,		I4_33	},
@@ -590,27 +590,27 @@ const struct mips_opcode mips_builtin_op
 {"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3_33	},
 {"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
 {"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
-{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1,		IOCT	},
 {"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 {"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 /* cfc2 is at the bottom of the table.  */
 /* cfc3 is at the bottom of the table.  */
 {"cftc1",   "d,E",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
 {"cftc1",   "d,T",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
-{"cftc2",   "d,E",	0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"cftc2",   "d,E",	0x41000025, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"cins32",  "t,r,+p,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"cins",    "t,r,+P,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	}, /* cins32 */
 {"cins",    "t,r,+p,+s",0x70000032, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"clo",     "U,s",      0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
 {"clz",     "U,s",      0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
-{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
 {"ctc1",    "t,G",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 {"ctc1",    "t,S",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 /* ctc2 is at the bottom of the table.  */
 /* ctc3 is at the bottom of the table.  */
 {"cttc1",   "t,g",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
 {"cttc1",   "t,S",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
-{"cttc2",   "t,g",	0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC,	0,		MT32	},
+{"cttc2",   "t,g",	0x41800025, 0xffe007ff,	TRAP|COD|RD_t|WR_CC,	0,		MT32,		IOCT	},
 {"cvt.d.l", "D,S",	0x46a00021, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I3_33	},
 {"cvt.d.s", "D,S",	0x46000021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
 {"cvt.d.w", "D,S",	0x46800021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
@@ -655,8 +655,8 @@ const struct mips_opcode mips_builtin_op
 {"ddivu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
 {"ddivu",   "d,v,t",	0,    (int) M_DDIVU_3,	INSN_MACRO,		0,		I3	},
 {"ddivu",   "d,v,I",	0,    (int) M_DDIVU_3I,	INSN_MACRO,		0,		I3	},
-{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		0,		I65	},
 {"dins",    "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
 {"dinsm",   "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
@@ -691,14 +691,14 @@ const struct mips_opcode mips_builtin_op
 {"dmaccu",  "d,s,t",	0x00000069, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmaccus", "d,s,t",	0x00000469, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmadd16", "s,t",      0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO,       0,		N411    },
-{"dmfc0",   "t,G",	0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,		0,		I3|IOCT	},
-{"dmfc0",   "t,+D",     0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
-{"dmfc0",   "t,G,H",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
+{"dmfc0",   "t,G",	0x40200000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I3	},
+{"dmfc0",   "t,+D",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
+{"dmfc0",   "t,G,H",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
 {"dmt",     "",		0x41600bc1, 0xffffffff, TRAP,			0,		MT32	},
 {"dmt",     "t",	0x41600bc1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	0,		I3|IOCT	},
-{"dmtc0",   "t,+D",     0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
-{"dmtc0",   "t,G,H",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
+{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I3	},
+{"dmtc0",   "t,+D",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
+{"dmtc0",   "t,G,H",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
 {"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,	0,		I3	},
 {"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,		I3      },
 {"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,	0,		I3	},
@@ -770,8 +770,8 @@ const struct mips_opcode mips_builtin_op
 {"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		0,		I3	},
 {"dvpe",    "",		0x41600001, 0xffffffff, TRAP,			0,		MT32	},
 {"dvpe",    "t",	0x41600001, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"emt",     "",		0x41600be1, 0xffffffff, TRAP,			0,		MT32	},
 {"emt",     "t",	0x41600be1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
 {"eret",    "",         0x42000018, 0xffffffff, NODS,      		0,		I3_32	},
@@ -836,10 +836,10 @@ const struct mips_opcode mips_builtin_op
 {"l.d",     "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	}, /* ldc1 */
 {"l.d",     "T,o(b)",	0,    (int) M_L_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"l.d",     "T,A(b)",	0,    (int) M_L_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
-{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2	},
-{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2	},
+{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT	},
+{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2,		IOCT	},
+{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT	},
+{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2,		IOCT	},
 {"ldl",	    "t,o(b)",	0x68000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
 {"ldl",	    "t,A(b)",	0,    (int) M_LDL_AB,	INSN_MACRO,		0,		I3	},
 {"ldr",	    "t,o(b)",	0x6c000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
@@ -862,18 +862,18 @@ const struct mips_opcode mips_builtin_op
 {"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I5_33|N55},
 {"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		0,		I1	},
-{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1	},
+{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"lwc1",    "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "E,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"lwc1",    "E,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"l.s",     "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	}, /* lwc1 */
 {"l.s",     "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1	},
-{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1	},
+{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1,		IOCT	},
+{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT	},
+{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"lwl",     "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lwl",     "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I1	},
 {"lcache",  "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I2	}, /* same */
@@ -936,20 +936,20 @@ const struct mips_opcode mips_builtin_op
 {"mftc0",   "d,E,H",	0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
 {"mftc1",   "d,T",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
 {"mftc1",   "d,E",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
-{"mftc2",   "d,E",	0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mftc2",   "d,E",	0x41000024, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"mftdsp",  "d",	0x41100021, 0xffff07ff, TRAP|WR_d,		0,		MT32	},
 {"mftgpr",  "d,t",	0x41000020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mfthc1",  "d,T",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
 {"mfthc1",  "d,E",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
-{"mfthc2",  "d,E",	0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mfthc2",  "d,E",	0x41000034, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT	},
 {"mfthi",   "d",	0x41010021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mfthi",   "d,*",	0x41010021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d",	0x41000021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d,*",	0x41000021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftr",    "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d,		0,		MT32	},
-{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1|IOCT	},
-{"mfc0",    "t,+D",     0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
-{"mfc0",    "t,G,H",    0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
+{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"mfc0",    "t,+D",0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
+{"mfc0",    "t,G,H",	0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
 {"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
@@ -1028,9 +1028,9 @@ const struct mips_opcode mips_builtin_op
 {"msubu",   "7,s,t",	0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D32	},
 {"mtpc",    "t,P",	0x4080c801, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
 {"mtps",    "t,P",	0x4080c800, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
-{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1|IOCT	},
-{"mtc0",    "t,+D",     0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
-{"mtc0",    "t,G,H",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
+{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1	},
+{"mtc0",    "t,+D",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
+{"mtc0",    "t,G,H",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
 {"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
@@ -1056,14 +1056,14 @@ const struct mips_opcode mips_builtin_op
 {"mttc0",   "t,G,H",	0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
 {"mttc1",   "t,S",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
 {"mttc1",   "t,G",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
-{"mttc2",   "t,g",	0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mttc2",   "t,g",	0x41800024, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT	},
 {"mttacx",  "t",	0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttacx",  "t,&",	0x41801021, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttdsp",  "t",	0x41808021, 0xffe0ffff, TRAP|RD_t,		0,		MT32	},
 {"mttgpr",  "t,d",	0x41800020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mtthc1",  "t,S",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
 {"mtthc1",  "t,G",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
-{"mtthc2",  "t,g",	0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mtthc2",  "t,g",	0x41800034, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT	},
 {"mtthi",   "t",	0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mtthi",   "t,&",	0x41800821, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttlo",   "t",	0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
@@ -1266,10 +1266,10 @@ const struct mips_opcode mips_builtin_op
 {"sdc1",    "E,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"sdc1",    "T,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
 {"sdc1",    "E,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
-{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000, SM|RD_C2|RD_b,		0,		I2	},
-{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2	},
-{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000, SM|RD_C3|RD_b,		0,		I2	},
-{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2	},
+{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I2,		IOCT	},
+{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2,		IOCT	},
+{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I2,		IOCT	},
+{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2,		IOCT	},
 {"s.d",     "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"s.d",     "T,o(b)",	0,    (int) M_S_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"s.d",     "T,A(b)",	0,    (int) M_S_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
@@ -1391,18 +1391,18 @@ const struct mips_opcode mips_builtin_op
 {"swapw",   "t,b",	0x70000014, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapwu",  "t,b",	0x70000015, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapd",   "t,b",	0x70000016, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
-{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1	},
-{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1	},
+{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1,		IOCT	},
+{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"swc1",    "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "E,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"swc1",    "E,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"s.s",     "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	}, /* swc1 */
 {"s.s",     "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1	},
-{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1	},
-{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1	},
-{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1	},
+{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1,		IOCT	},
+{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1,		IOCT	},
+{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1,		IOCT	},
+{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1,		IOCT	},
 {"swl",     "t,o(b)",	0xa8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"swl",     "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I1	},
 {"scache",  "t,o(b)",	0xa8000000, 0xfc000000,	RD_t|RD_b,		0,		I2	}, /* same */
@@ -1579,47 +1579,47 @@ const struct mips_opcode mips_builtin_op
 
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
-{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT	},
+{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT	},
+{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT	},
+{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT	},
+{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT	},
+{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
 {"dmfc2",   "t,i",	0x48200000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		IOCT	},
-{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3	},
-{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64	},
+{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3,		IOCT	},
+{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64,		IOCT	},
 {"dmtc2",   "t,i",	0x48a00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		IOCT	},
-{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3	},
-{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64	},
-{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32	},
-{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1	},
-{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32	},
-{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
+{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3,		IOCT	},
+{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64,		IOCT	},
+{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT	},
+{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32,		IOCT	},
+{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33,		IOCT	},
+{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1,		IOCT	},
+{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32,		IOCT	},
+{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
+{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
+{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT	},
 
 /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X 
    instructions, so they are here for the latters to take precedence.  */
-{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
-{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 	0,		I3	},
-{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC,	0,		I3	},
-{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"mfc3",    "t,G,H",    0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 	0,		I32     },
-{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1	},
-{"mtc3",    "t,G,H",    0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   0,		I32     },
+{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT	},
+{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT	},
+{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I3,		IOCT	},
+{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I3,		IOCT	},
+{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT	},
+{"mfc3",    "t,G,H",	0x4c000000, 0xffe007f8,	LCD|WR_t|RD_C3,		0,		I32,		IOCT	},
+{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1,		IOCT	},
+{"mtc3",    "t,G,H",	0x4c800000, 0xffe007f8,	COD|RD_t|WR_C3|WR_CC,	0,		I32,		IOCT	},
 
   /* Conflicts with the 4650's "mul" instruction.  Nobody's using the
      4010 any more, so move this insn out of the way.  If the object
@@ -1909,10 +1909,10 @@ const struct mips_opcode mips_builtin_op
 {"dpsqx_s.w.ph", "7,s,t", 0x7c000670, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 {"dpsqx_sa.w.ph", "7,s,t", 0x7c0006f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 /* Move bc0* after mftr and mttr to avoid opcode collision.  */
-{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
+{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT	},
+{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT	},
 /* ST Microelectronics Loongson-2E and -2F.  */
 {"mult.g",	"d,s,t",	0x7c000018,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2E	},
 {"mult.g",	"d,s,t",	0x70000010,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2F	},
@@ -2072,14 +2072,14 @@ const struct mips_opcode mips_builtin_op
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
    disassembler recognizes more specific versions first.  */
-{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1	},
+{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
 {"c1",      "C",	0x46000000, 0xfe000000,	FP_S,			0,		I1	},
-{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1	},
-{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1	},
-{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1	},
+{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
+{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1,		IOCT	},
+{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1,		IOCT	},
 {"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1	},
-{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1	}
+{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1,		IOCT	},
+{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1,		IOCT	},
 };
 
 #define MIPS_NUM_OPCODES \
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2011-10-24 23:03:27.755861452 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2011-10-24 23:03:27.875859808 +0100
@@ -514,11 +514,6 @@ static int mips_32bitmode = 0;
 /* True if CPU has seq/sne and seqi/snei instructions.  */
 #define CPU_HAS_SEQ(CPU)	((CPU) == CPU_OCTEON)
 
-/* True if CPU does not implement the all the coprocessor insns.  For these
-   CPUs only those COP insns are accepted that are explicitly marked to be
-   available on the CPU.  ISA membership for COP insns is ignored.  */
-#define NO_ISA_COP(CPU)		((CPU) == CPU_OCTEON)
-
 /* True if mflo and mfhi can be immediately followed by instructions
    which write to the HI and LO registers.
 
@@ -589,15 +584,6 @@ static int mips_32bitmode = 0;
 #define MF_HILO_INSN(PINFO) \
   ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
 
-/* Returns true for a (non floating-point) coprocessor instruction.  Reading
-   or writing the condition code is only possible on the coprocessors and
-   these insns are not marked with INSN_COP.  Thus for these insns use the
-   condition-code flags.  */
-#define COP_INSN(PINFO)							\
-  (PINFO != INSN_MACRO							\
-   && ((PINFO) & (FP_S | FP_D)) == 0					\
-   && ((PINFO) & (INSN_COP | INSN_READ_COND_CODE | INSN_WRITE_COND_CODE)))
-
 /* Whether code compression (either of the MIPS16 or the microMIPS ASEs)
    has been selected.  This implies, in particular, that addresses of text
    labels have their LSB set.  */
@@ -2228,12 +2214,6 @@ is_opcode_valid (const struct mips_opcod
   if (mips_opts.ase_mcu)
     isa |= INSN_MCU;
 
-  /* Don't accept instructions based on the ISA if the CPU does not implement
-     all the coprocessor insns. */
-  if (NO_ISA_COP (mips_opts.arch)
-      && COP_INSN (mo->pinfo))
-    isa = 0;
-
   if (!OPCODE_IS_MEMBER (mo, isa, mips_opts.arch))
     return FALSE;
 
@@ -8288,15 +8268,6 @@ macro (struct mips_cl_insn *ip, char *st
       tempreg = AT;
       used_at = 1;
     ld_noat:
-      if (coproc
-	  && NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & (INSN2_M_FP_S | INSN2_M_FP_D)) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       if (offset_expr.X_op != O_constant
 	  && offset_expr.X_op != O_symbol)
 	{
@@ -9213,14 +9184,6 @@ macro (struct mips_cl_insn *ip, char *st
       s = "c3";
     copz:
       gas_assert (!mips_opts.micromips);
-      if (NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       /* For now we just do C (same as Cz).  The parameter will be
          stored in insn_opcode by mips_ip.  */
       macro_build (NULL, s, "C", ip->insn_opcode);

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2011-10-31 12:47 ` Maciej W. Rozycki
@ 2011-11-17 18:45   ` Richard Sandiford
  2012-08-10 11:08     ` Maciej W. Rozycki
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2011-11-17 18:45 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: David Daney, Andrew Pinski, binutils

"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> @@ -830,37 +833,38 @@ static const unsigned int mips_isa_table
>     ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
>     test, or zero if no CPU specific ISA test is desired.  */
>  
> -#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
> -    (((isa & INSN_ISA_MASK) != 0                                        \
> -      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
> -      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
> -           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
> -     || ((isa & ~INSN_ISA_MASK)                                         \
> -          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
> -     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
> -     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
> -     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
> -     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
> -     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
> -     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
> -     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
> -	  || cpu == CPU_R16000)						\
> -	 && ((insn)->membership & INSN_10000) != 0)			\
> -     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
> -     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
> -     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
> -     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
> -     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
> -     || (cpu == CPU_LOONGSON_2E                                         \
> -         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
> -     || (cpu == CPU_LOONGSON_2F                                         \
> -         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
> -     || (cpu == CPU_LOONGSON_3A                                         \
> -         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
> -     || (cpu == CPU_OCTEON						\
> -	 && ((insn)->membership & INSN_OCTEON) != 0)			\
> -     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
> -     || 0)	/* Please keep this term for easier source merging.  */
> +#define OPCODE_IS_MEMBER(insn, isa, cpu)				    \
> +    ((((isa & INSN_ISA_MASK) != 0					    \
> +       && ((insn)->membership & INSN_ISA_MASK) != 0			    \
> +       && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>		    \
> +	    (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)	    \
> +      || ((isa & ~INSN_ISA_MASK)					    \
> +	   & ((insn)->membership & ~INSN_ISA_MASK)) != 0		    \
> +      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	    \
> +      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	    \
> +      || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	    \
> +      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	    \
> +      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	    \
> +      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	    \
> +      || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	    \
> +	   || cpu == CPU_R16000)					    \
> +	  && ((insn)->membership & INSN_10000) != 0)			    \
> +      || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	    \
> +      || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	    \
> +      || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	    \
> +      || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	    \
> +      || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	    \
> +      || (cpu == CPU_LOONGSON_2E					    \
> +	  && ((insn)->membership & INSN_LOONGSON_2E) != 0)		    \
> +      || (cpu == CPU_LOONGSON_2F					    \
> +	  && ((insn)->membership & INSN_LOONGSON_2F) != 0)		    \
> +      || (cpu == CPU_LOONGSON_3A					    \
> +	  && ((insn)->membership & INSN_LOONGSON_3A) != 0)		    \
> +      || (cpu == CPU_OCTEON && ((insn)->membership & INSN_OCTEON) != 0)    \
> +      || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)	    \
> +      || 0)	/* Please keep this term for easier source merging.  */	    \
> +     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	    \

Looks like a typo for "((insn)->exclusions & INSN_OCTEON) == 0".

To help avoid this sort of thing, and to avoid making the patch
unnecessarily Octeon-specific, I think the CPU/mask test should
be split out.  Specifically:

/* Return true if the given CPU is included in INSN_* mask MASK.  */

static bfd_boolean
cpu_is_member (int cpu, unsigned int mask)
{
  switch (cpu)
    {
    case CPU_R4650:
    case CPU_RM7000:
    case CPU_RM9000:
      return (mask & INSN_4650) != 0;

    case CPU_R4010:
      return (mask & INSN_4010) != 0;

    case CPU_VR4100:
      return (mask & INSN_4100) != 0;

    case CPU_R3900:
      return (mask & INSN_3900) != 0;

    case CPU_R10000:
    case CPU_R12000:
    case CPU_R14000:
    case CPU_R16000:
      return (mask & INSN_10000) != 0;

    case CPU_SB1:
      return (mask & INSN_SB1) != 0;

    case CPU_R4111:
      return (mask & INSN_4111) != 0;

    case CPU_VR4120:
      return (mask & INSN_4120) != 0;

    case CPU_VR5400:
      return (mask & INSN_5400) != 0;

    case CPU_VR5500:
      return (mask & INSN_5500) != 0;

    case CPU_LOONGSON_2E:
      return (mask & INSN_LOONGSON_2E) != 0;

    case CPU_LOONGSON_2F:
      return (mask & INSN_LOONGSON_2F) != 0;

    case CPU_LOONGSON_3A:
      return (mask & INSN_LOONGSON_3A) != 0;

    case CPU_OCTEON:
      return (mask & INSN_OCTEON) != 0;

    case CPU_XLR:
      return (mask & INSN_XLR) != 0;

    default:
      return FALSE;
}

/* Return true if instruction MO is available when assembling for
   the given ISA and CPU.  */

static bfd_boolean
opcode_is_member (const struct mips_opcode *mo, int isa, int cpu)
{
  if (!cpu_is_member (cpu, mo->exclusions))
    {
      /* Test for ISA level compatibility.  */
      if ((isa & INSN_ISA_MASK) != 0
	  && (mo->membership & INSN_ISA_MASK) != 0
	  && ((mips_isa_table[(isa & INSN_ISA_MASK) - 1]
	       >> ((mo->membership & INSN_ISA_MASK) - 1)) & 1) != 0)
	return TRUE;

      /* Test for ASE compatibility.  */
      if (((isa & ~INSN_ISA_MASK) & (mo->membership & ~INSN_ISA_MASK)) != 0)
	return TRUE;

      /* Test for processor-specific extensions.  */
      if (cpu_is_member (cpu, mo->membership))
	return TRUE;
    }
  return FALSE;
}

(untested, so please fix the inevitable errors).

> +NO_WFIELD = @NO_WFIELD@

I think this name loses too much information.  Just call it
NO_WMISSING_FIELD_INITIALIZERS.

OK with those changes.

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2011-11-17 18:45   ` Richard Sandiford
@ 2012-08-10 11:08     ` Maciej W. Rozycki
  2012-08-12 18:33       ` Richard Sandiford
  2013-06-17 11:51       ` Alan Modra
  0 siblings, 2 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2012-08-10 11:08 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: David Daney, Andrew Pinski, binutils

On Thu, 17 Nov 2011, Richard Sandiford wrote:

> > @@ -830,37 +833,38 @@ static const unsigned int mips_isa_table
> >     ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
> >     test, or zero if no CPU specific ISA test is desired.  */
> >  
> > -#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
> > -    (((isa & INSN_ISA_MASK) != 0                                        \
> > -      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
> > -      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
> > -           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
> > -     || ((isa & ~INSN_ISA_MASK)                                         \
> > -          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
> > -     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
> > -     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
> > -     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
> > -     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
> > -     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
> > -     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
> > -     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
> > -	  || cpu == CPU_R16000)						\
> > -	 && ((insn)->membership & INSN_10000) != 0)			\
> > -     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
> > -     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
> > -     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
> > -     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
> > -     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
> > -     || (cpu == CPU_LOONGSON_2E                                         \
> > -         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
> > -     || (cpu == CPU_LOONGSON_2F                                         \
> > -         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
> > -     || (cpu == CPU_LOONGSON_3A                                         \
> > -         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
> > -     || (cpu == CPU_OCTEON						\
> > -	 && ((insn)->membership & INSN_OCTEON) != 0)			\
> > -     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
> > -     || 0)	/* Please keep this term for easier source merging.  */
> > +#define OPCODE_IS_MEMBER(insn, isa, cpu)				    \
> > +    ((((isa & INSN_ISA_MASK) != 0					    \
> > +       && ((insn)->membership & INSN_ISA_MASK) != 0			    \
> > +       && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>		    \
> > +	    (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)	    \
> > +      || ((isa & ~INSN_ISA_MASK)					    \
> > +	   & ((insn)->membership & ~INSN_ISA_MASK)) != 0		    \
> > +      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	    \
> > +      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	    \
> > +      || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	    \
> > +      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	    \
> > +      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	    \
> > +      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	    \
> > +      || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	    \
> > +	   || cpu == CPU_R16000)					    \
> > +	  && ((insn)->membership & INSN_10000) != 0)			    \
> > +      || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	    \
> > +      || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	    \
> > +      || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	    \
> > +      || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	    \
> > +      || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	    \
> > +      || (cpu == CPU_LOONGSON_2E					    \
> > +	  && ((insn)->membership & INSN_LOONGSON_2E) != 0)		    \
> > +      || (cpu == CPU_LOONGSON_2F					    \
> > +	  && ((insn)->membership & INSN_LOONGSON_2F) != 0)		    \
> > +      || (cpu == CPU_LOONGSON_3A					    \
> > +	  && ((insn)->membership & INSN_LOONGSON_3A) != 0)		    \
> > +      || (cpu == CPU_OCTEON && ((insn)->membership & INSN_OCTEON) != 0)    \
> > +      || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)	    \
> > +      || 0)	/* Please keep this term for easier source merging.  */	    \
> > +     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	    \
> 
> Looks like a typo for "((insn)->exclusions & INSN_OCTEON) == 0".

 Hmm, where's the typo?  That's supposed to be true as long as the CPU is 
other than Octeon or the Octeon exclusion bit is zero.  Did I get that 
wrong?

 However I do like your proposal:

> To help avoid this sort of thing, and to avoid making the patch
> unnecessarily Octeon-specific, I think the CPU/mask test should
> be split out.  Specifically:
> 
> /* Return true if the given CPU is included in INSN_* mask MASK.  */
> 
> static bfd_boolean
> cpu_is_member (int cpu, unsigned int mask)
> {
>   switch (cpu)
>     {
>     case CPU_R4650:
>     case CPU_RM7000:
>     case CPU_RM9000:
>       return (mask & INSN_4650) != 0;
> 
>     case CPU_R4010:
>       return (mask & INSN_4010) != 0;
> 
>     case CPU_VR4100:
>       return (mask & INSN_4100) != 0;
> 
>     case CPU_R3900:
>       return (mask & INSN_3900) != 0;
> 
>     case CPU_R10000:
>     case CPU_R12000:
>     case CPU_R14000:
>     case CPU_R16000:
>       return (mask & INSN_10000) != 0;
> 
>     case CPU_SB1:
>       return (mask & INSN_SB1) != 0;
> 
>     case CPU_R4111:
>       return (mask & INSN_4111) != 0;
> 
>     case CPU_VR4120:
>       return (mask & INSN_4120) != 0;
> 
>     case CPU_VR5400:
>       return (mask & INSN_5400) != 0;
> 
>     case CPU_VR5500:
>       return (mask & INSN_5500) != 0;
> 
>     case CPU_LOONGSON_2E:
>       return (mask & INSN_LOONGSON_2E) != 0;
> 
>     case CPU_LOONGSON_2F:
>       return (mask & INSN_LOONGSON_2F) != 0;
> 
>     case CPU_LOONGSON_3A:
>       return (mask & INSN_LOONGSON_3A) != 0;
> 
>     case CPU_OCTEON:
>       return (mask & INSN_OCTEON) != 0;
> 
>     case CPU_XLR:
>       return (mask & INSN_XLR) != 0;
> 
>     default:
>       return FALSE;
> }
> 
> /* Return true if instruction MO is available when assembling for
>    the given ISA and CPU.  */
> 
> static bfd_boolean
> opcode_is_member (const struct mips_opcode *mo, int isa, int cpu)
> {
>   if (!cpu_is_member (cpu, mo->exclusions))
>     {
>       /* Test for ISA level compatibility.  */
>       if ((isa & INSN_ISA_MASK) != 0
> 	  && (mo->membership & INSN_ISA_MASK) != 0
> 	  && ((mips_isa_table[(isa & INSN_ISA_MASK) - 1]
> 	       >> ((mo->membership & INSN_ISA_MASK) - 1)) & 1) != 0)
> 	return TRUE;
> 
>       /* Test for ASE compatibility.  */
>       if (((isa & ~INSN_ISA_MASK) & (mo->membership & ~INSN_ISA_MASK)) != 0)
> 	return TRUE;
> 
>       /* Test for processor-specific extensions.  */
>       if (cpu_is_member (cpu, mo->membership))
> 	return TRUE;
>     }
>   return FALSE;
> }
> 
> (untested, so please fix the inevitable errors).

except that OPCODE_IS_MEMBER is used in several places both in GAS (for 
assembly) and opcodes (for disassembly), so this have to be reachable from 
the header and a static unused function is going to trigger warnings.

 To address this I have decided to make it "static inline" instead as this 
seems to matter for performance and we rely on such an arrangement in many 
places already, including generic code, even though it's not supported by 
old C compilers.  Let me know if you'd rather I exported it from opcodes 
instead.

> > +NO_WFIELD = @NO_WFIELD@
> 
> I think this name loses too much information.  Just call it
> NO_WMISSING_FIELD_INITIALIZERS.

 Sure.

> OK with those changes.

 I decided to keep the INSN argument's name and reused the old comment.  
Let me know if that's OK.  No regressions on the MIPS or other targets.

2012-08-10  Richard Sandiford  <rdsandiford@googlemail.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

	include/opcode/
	* mips.h (mips_opcode): Add the exclusions field.
	(OPCODE_IS_MEMBER): Remove macro.
	(cpu_is_member): New inline function.
	(opcode_is_member): Likewise.

2012-08-10  Maciej W. Rozycki  <macro@codesourcery.com>

	opcodes/
	* micromips-opc.c (micromips_opcodes): Update comment.
	* mips-opc.c (mips_builtin_opcodes): Likewise.  Mark coprocessor
	instructions for IOCT as appropriate.
	* mips-dis.c (print_insn_mips): Replace OPCODE_IS_MEMBER with
	opcode_is_member.
	* configure.in: Substitute NO_WMISSING_FIELD_INITIALIZERS with
	the result of a check for the -Wno-missing-field-initializers
	GCC option.
	* Makefile.am (NO_WMISSING_FIELD_INITIALIZERS): New variable.
	(mips-opc.lo): Pass $(NO_WMISSING_FIELD_INITIALIZERS) to
	compilation.
	(mips16-opc.lo): Likewise.
	(micromips-opc.lo): Likewise.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* Makefile.in: Regenerate.

2012-08-10  Maciej W. Rozycki  <macro@codesourcery.com>

	gas/
	* config/tc-mips.c (NO_ISA_COP, COP_INSN): Remove macros.
	(is_opcode_valid): Remove coprocessor instruction exclusions.
	Replace OPCODE_IS_MEMBER with opcode_is_member.
	(is_opcode_valid_16): Replace OPCODE_IS_MEMBER with
	opcode_is_member.
	(macro): Remove coprocessor instruction exclusions.

binutils-opcode-exclude.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2012-08-10 00:43:35.031296636 +0100
@@ -505,11 +505,6 @@ static int mips_32bitmode = 0;
 /* True if CPU has seq/sne and seqi/snei instructions.  */
 #define CPU_HAS_SEQ(CPU)	(CPU_IS_OCTEON (CPU))
 
-/* True if CPU does not implement the all the coprocessor insns.  For these
-   CPUs only those COP insns are accepted that are explicitly marked to be
-   available on the CPU.  ISA membership for COP insns is ignored.  */
-#define NO_ISA_COP(CPU)		(CPU_IS_OCTEON (CPU))
-
 /* True if mflo and mfhi can be immediately followed by instructions
    which write to the HI and LO registers.
 
@@ -580,15 +575,6 @@ static int mips_32bitmode = 0;
 #define MF_HILO_INSN(PINFO) \
   ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
 
-/* Returns true for a (non floating-point) coprocessor instruction.  Reading
-   or writing the condition code is only possible on the coprocessors and
-   these insns are not marked with INSN_COP.  Thus for these insns use the
-   condition-code flags.  */
-#define COP_INSN(PINFO)							\
-  (PINFO != INSN_MACRO							\
-   && ((PINFO) & (FP_S | FP_D)) == 0					\
-   && ((PINFO) & (INSN_COP | INSN_READ_COND_CODE | INSN_WRITE_COND_CODE)))
-
 /* Whether code compression (either of the MIPS16 or the microMIPS ASEs)
    has been selected.  This implies, in particular, that addresses of text
    labels have their LSB set.  */
@@ -2221,13 +2207,7 @@ is_opcode_valid (const struct mips_opcod
   if (mips_opts.ase_mcu)
     isa |= INSN_MCU;
 
-  /* Don't accept instructions based on the ISA if the CPU does not implement
-     all the coprocessor insns. */
-  if (NO_ISA_COP (mips_opts.arch)
-      && COP_INSN (mo->pinfo))
-    isa = 0;
-
-  if (!OPCODE_IS_MEMBER (mo, isa, mips_opts.arch))
+  if (!opcode_is_member (mo, isa, mips_opts.arch))
     return FALSE;
 
   /* Check whether the instruction or macro requires single-precision or
@@ -2259,7 +2239,7 @@ is_opcode_valid (const struct mips_opcod
 static bfd_boolean
 is_opcode_valid_16 (const struct mips_opcode *mo)
 {
-  return OPCODE_IS_MEMBER (mo, mips_opts.isa, mips_opts.arch) ? TRUE : FALSE;
+  return opcode_is_member (mo, mips_opts.isa, mips_opts.arch);
 }
 
 /* Return TRUE if the size of the microMIPS opcode MO matches one
@@ -8265,15 +8245,6 @@ macro (struct mips_cl_insn *ip)
       tempreg = AT;
       used_at = 1;
     ld_noat:
-      if (coproc
-	  && NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & (INSN2_M_FP_S | INSN2_M_FP_D)) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       if (offset_expr.X_op != O_constant
 	  && offset_expr.X_op != O_symbol)
 	{
@@ -9199,14 +9170,6 @@ macro (struct mips_cl_insn *ip)
       s = "c3";
     copz:
       gas_assert (!mips_opts.micromips);
-      if (NO_ISA_COP (mips_opts.arch)
-	  && (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0)
-	{
-	  as_bad (_("Opcode not supported on this processor: %s"),
-		  mips_cpu_info_from_arch (mips_opts.arch)->name);
-	  break;
-	}
-
       /* For now we just do C (same as Cz).  The parameter will be
          stored in insn_opcode by mips_ip.  */
       macro_build (NULL, s, "C", ip->insn_opcode);
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2012-08-10 00:43:34.991783785 +0100
@@ -25,6 +25,8 @@
 #ifndef _MIPS_H_
 #define _MIPS_H_
 
+#include "bfd.h"
+
 /* These are bit masks and shift counts to use to access the various
    fields of an instruction.  To retrieve the X field of an
    instruction, use the expression
@@ -353,6 +355,9 @@ struct mips_opcode
   /* A collection of bits describing the instruction sets of which this
      instruction or macro is a member. */
   unsigned long membership;
+  /* A collection of bits describing the instruction sets of which this
+     instruction or macro is not a member.  */
+  unsigned long exclusions;
 };
 
 /* These are the characters which may appear in the args field of an
@@ -829,46 +834,102 @@ static const unsigned int mips_isa_table
 #define CPU_OCTEON2	6502
 #define CPU_XLR     	887682   	/* decimal 'XLR'   */
 
+/* Return true if the given CPU is included in INSN_* mask MASK.  */
+
+static inline bfd_boolean
+cpu_is_member (int cpu, unsigned int mask)
+{
+  switch (cpu)
+    {
+    case CPU_R4650:
+    case CPU_RM7000:
+    case CPU_RM9000:
+      return (mask & INSN_4650) != 0;
+
+    case CPU_R4010:
+      return (mask & INSN_4010) != 0;
+
+    case CPU_VR4100:
+      return (mask & INSN_4100) != 0;
+
+    case CPU_R3900:
+      return (mask & INSN_3900) != 0;
+
+    case CPU_R10000:
+    case CPU_R12000:
+    case CPU_R14000:
+    case CPU_R16000:
+      return (mask & INSN_10000) != 0;
+
+    case CPU_SB1:
+      return (mask & INSN_SB1) != 0;
+
+    case CPU_R4111:
+      return (mask & INSN_4111) != 0;
+
+    case CPU_VR4120:
+      return (mask & INSN_4120) != 0;
+
+    case CPU_VR5400:
+      return (mask & INSN_5400) != 0;
+
+    case CPU_VR5500:
+      return (mask & INSN_5500) != 0;
+
+    case CPU_LOONGSON_2E:
+      return (mask & INSN_LOONGSON_2E) != 0;
+
+    case CPU_LOONGSON_2F:
+      return (mask & INSN_LOONGSON_2F) != 0;
+
+    case CPU_LOONGSON_3A:
+      return (mask & INSN_LOONGSON_3A) != 0;
+
+    case CPU_OCTEON:
+      return (mask & INSN_OCTEON) != 0;
+
+    case CPU_OCTEONP:
+      return (mask & INSN_OCTEONP) != 0;
+
+    case CPU_OCTEON2:
+      return (mask & INSN_OCTEON2) != 0;
+
+    case CPU_XLR:
+      return (mask & INSN_XLR) != 0;
+
+    default:
+      return FALSE;
+    }
+}
+
 /* 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/ASE bitmask to test against; and CPU is the CPU specific ISA to
-   test, or zero if no CPU specific ISA test is desired.  */
+   test, or zero if no CPU specific ISA test is desired.  Return true
+   if instruction INSN is available to the given ISA and CPU. */
 
-#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
-    (((isa & INSN_ISA_MASK) != 0                                        \
-      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
-      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
-           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
-     || ((isa & ~INSN_ISA_MASK)                                         \
-          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
-     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
-     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
-     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
-     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
-     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
-	  || cpu == CPU_R16000)						\
-	 && ((insn)->membership & INSN_10000) != 0)			\
-     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
-     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
-     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
-     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
-     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
-     || (cpu == CPU_LOONGSON_2E                                         \
-         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
-     || (cpu == CPU_LOONGSON_2F                                         \
-         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
-     || (cpu == CPU_LOONGSON_3A                                         \
-         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
-     || (cpu == CPU_OCTEON						\
-	 && ((insn)->membership & INSN_OCTEON) != 0)			\
-     || (cpu == CPU_OCTEONP						\
-	 && ((insn)->membership & INSN_OCTEONP) != 0)			\
-     || (cpu == CPU_OCTEON2						\
-	 && ((insn)->membership & INSN_OCTEON2) != 0)			\
-     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
-     || 0)	/* Please keep this term for easier source merging.  */
+static inline bfd_boolean
+opcode_is_member (const struct mips_opcode *insn, int isa, int cpu)
+{
+  if (!cpu_is_member (cpu, insn->exclusions))
+    {
+      /* Test for ISA level compatibility.  */
+      if ((isa & INSN_ISA_MASK) != 0
+	  && (insn->membership & INSN_ISA_MASK) != 0
+	  && ((mips_isa_table[(isa & INSN_ISA_MASK) - 1]
+	       >> ((insn->membership & INSN_ISA_MASK) - 1)) & 1) != 0)
+	return TRUE;
+
+      /* Test for ASE compatibility.  */
+      if (((isa & ~INSN_ISA_MASK) & (insn->membership & ~INSN_ISA_MASK)) != 0)
+	return TRUE;
+
+      /* Test for processor-specific extensions.  */
+      if (cpu_is_member (cpu, insn->membership))
+	return TRUE;
+    }
+  return FALSE;
+}
 
 /* This is a list of macro expanded instructions.
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.am
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.am	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.am	2012-08-10 00:43:34.991783785 +0100
@@ -11,6 +11,7 @@ BFDDIR = $(srcdir)/../bfd
 
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
+NO_WMISSING_FIELD_INITIALIZERS = @NO_WMISSING_FIELD_INITIALIZERS@
 AM_CFLAGS = $(WARN_CFLAGS)
 
 COMPILE_FOR_BUILD = $(CC_FOR_BUILD) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -528,6 +529,15 @@ ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 $(srcdir)/rl78-decode.c: @MAINT@ $(srcdir)/rl78-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rl78-decode.opc > $(srcdir)/rl78-decode.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/Makefile.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/Makefile.in	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/Makefile.in	2012-08-10 00:52:37.141490983 +0100
@@ -54,6 +54,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../b
 	$(top_srcdir)/../config/override.m4 \
 	$(top_srcdir)/../config/po.m4 \
 	$(top_srcdir)/../config/progtest.m4 \
+	$(top_srcdir)/../config/warnings.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
 	$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
 	$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.in
@@ -195,6 +196,7 @@ MSGMERGE = @MSGMERGE@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NO_WERROR = @NO_WERROR@
+NO_WMISSING_FIELD_INITIALIZERS = @NO_WMISSING_FIELD_INITIALIZERS@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OTOOL = @OTOOL@
@@ -1377,6 +1379,15 @@ ia64-opc.lo: $(srcdir)/ia64-asmtab.c
 $(srcdir)/rl78-decode.c: @MAINT@ $(srcdir)/rl78-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rl78-decode.opc > $(srcdir)/rl78-decode.c
 
+micromips-opc.lo: micromips-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
+mips-opc.lo: mips-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
+mips16-opc.lo: mips16-opc.c
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c
 
Index: binutils-fsf-trunk-quilt/opcodes/aclocal.m4
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/aclocal.m4	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/aclocal.m4	2012-08-10 00:52:33.921818456 +0100
@@ -978,6 +978,7 @@ m4_include([../config/nls.m4])
 m4_include([../config/override.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
+m4_include([../config/warnings.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
Index: binutils-fsf-trunk-quilt/opcodes/configure
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/configure	2012-08-10 00:52:34.741496054 +0100
@@ -640,6 +640,7 @@ INSTALL_LIBBFD_TRUE
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+NO_WMISSING_FIELD_INITIALIZERS
 NO_WERROR
 WARN_CFLAGS
 OTOOL64
@@ -11134,7 +11135,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11137 "configure"
+#line 11138 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11240,7 +11241,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11243 "configure"
+#line 11244 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11561,6 +11562,51 @@ fi
 
 
 
+NO_WMISSING_FIELD_INITIALIZERS=
+save_CFLAGS="$CFLAGS"
+for real_option in -Wno-missing-field-initializers; do
+  # Do the check with the no- prefix removed since gcc silently
+  # accepts any -Wno-* option on purpose
+  case $real_option in
+    -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
+    *) option=$real_option ;;
+  esac
+  as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
+$as_echo_n "checking whether $CC supports $option... " >&6; }
+if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  CFLAGS="$option"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_acx_Woption=yes"
+else
+  eval "$as_acx_Woption=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+eval ac_res=\$$as_acx_Woption
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
+  NO_WMISSING_FIELD_INITIALIZERS="$NO_WMISSING_FIELD_INITIALIZERS${NO_WMISSING_FIELD_INITIALIZERS:+ }$real_option"
+fi
+  done
+CFLAGS="$save_CFLAGS"
+
 
 ac_config_headers="$ac_config_headers config.h:config.in"
 
Index: binutils-fsf-trunk-quilt/opcodes/configure.in
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/configure.in	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/configure.in	2012-08-10 00:43:35.021496982 +0100
@@ -42,6 +42,8 @@ AC_ARG_ENABLE(targets,
 esac])dnl
 
 AM_BINUTILS_WARNINGS
+ACX_PROG_CC_WARNING_OPTS([-Wno-missing-field-initializers],
+			 [NO_WMISSING_FIELD_INITIALIZERS])
 
 AC_CONFIG_HEADERS(config.h:config.in)
 
Index: binutils-fsf-trunk-quilt/opcodes/micromips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/micromips-opc.c	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/micromips-opc.c	2012-08-10 00:43:35.021496982 +0100
@@ -115,7 +115,7 @@ const struct mips_opcode micromips_opcod
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership */
+/* name,    args,	match,      mask,	pinfo,			pinfo2,		membership,	[exclusions] */
 {"pref",    "k,~(b)",	0x60002000, 0xfc00f000,	RD_b,			0,		I1	},
 {"pref",    "k,o(b)",	0,    (int) M_PREF_OB,	INSN_MACRO,		0,		I1	},
 {"pref",    "k,A(b)",	0,    (int) M_PREF_AB,	INSN_MACRO,		0,		I1	},
Index: binutils-fsf-trunk-quilt/opcodes/mips-dis.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips-dis.c	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/mips-dis.c	2012-08-10 00:43:35.031296636 +0100
@@ -1562,7 +1562,7 @@ print_insn_mips (bfd_vma memaddr,
 	      const char *d;
 
 	      /* We always allow to disassemble the jalx instruction.  */
-	      if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
+	      if (!opcode_is_member (op, mips_isa, mips_processor)
 		  && strcmp (op->name, "jalx"))
 		continue;
 
Index: binutils-fsf-trunk-quilt/opcodes/mips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips-opc.c	2012-08-10 00:40:01.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/mips-opc.c	2012-08-10 00:43:35.021496982 +0100
@@ -197,7 +197,7 @@ const struct mips_opcode mips_builtin_op
 /* These instructions appear first so that the disassembler will find
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
-/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership */
+/* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership,	[exclusions] */
 {"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	0,		I4_32|G3	},
 {"pref",    "k,A(b)",	0,    (int) M_PREF_AB,	INSN_MACRO,		0,		I4_32|G3	},
 {"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S,		0,		I4_33	},
@@ -593,27 +593,27 @@ const struct mips_opcode mips_builtin_op
 {"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3_33	},
 {"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
 {"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
-{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 {"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 /* cfc2 is at the bottom of the table.  */
 /* cfc3 is at the bottom of the table.  */
 {"cftc1",   "d,E",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
 {"cftc1",   "d,T",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
-{"cftc2",   "d,E",	0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"cftc2",   "d,E",	0x41000025, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"cins32",  "t,r,+p,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"cins",    "t,r,+P,+S",0x70000033, 0xfc00003f, WR_t|RD_s,		0,		IOCT	}, /* cins32 */
 {"cins",    "t,r,+p,+s",0x70000032, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"clo",     "U,s",      0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
 {"clz",     "U,s",      0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
-{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"ctc1",    "t,G",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 {"ctc1",    "t,S",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 /* ctc2 is at the bottom of the table.  */
 /* ctc3 is at the bottom of the table.  */
 {"cttc1",   "t,g",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
 {"cttc1",   "t,S",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
-{"cttc2",   "t,g",	0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC,	0,		MT32	},
+{"cttc2",   "t,g",	0x41800025, 0xffe007ff,	TRAP|COD|RD_t|WR_CC,	0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"cvt.d.l", "D,S",	0x46a00021, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I3_33	},
 {"cvt.d.s", "D,S",	0x46000021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
 {"cvt.d.w", "D,S",	0x46800021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
@@ -658,8 +658,8 @@ const struct mips_opcode mips_builtin_op
 {"ddivu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
 {"ddivu",   "d,v,t",	0,    (int) M_DDIVU_3,	INSN_MACRO,		0,		I3	},
 {"ddivu",   "d,v,I",	0,    (int) M_DDIVU_3I,	INSN_MACRO,		0,		I3	},
-{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		0,		I65	},
 {"dins",    "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
 {"dinsm",   "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
@@ -694,14 +694,14 @@ const struct mips_opcode mips_builtin_op
 {"dmaccu",  "d,s,t",	0x00000069, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmaccus", "d,s,t",	0x00000469, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
 {"dmadd16", "s,t",      0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO,       0,		N411    },
-{"dmfc0",   "t,G",	0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,		0,		I3|IOCT	},
-{"dmfc0",   "t,+D",     0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
-{"dmfc0",   "t,G,H",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64|IOCT},
+{"dmfc0",   "t,G",	0x40200000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I3	},
+{"dmfc0",   "t,+D",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
+{"dmfc0",   "t,G,H",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
 {"dmt",     "",		0x41600bc1, 0xffffffff, TRAP,			0,		MT32	},
 {"dmt",     "t",	0x41600bc1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	0,		I3|IOCT	},
-{"dmtc0",   "t,+D",     0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
-{"dmtc0",   "t,G,H",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64|IOCT},
+{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I3	},
+{"dmtc0",   "t,+D",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
+{"dmtc0",   "t,G,H",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
 {"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,	0,		I3	},
 {"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,		I3      },
 {"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,	0,		I3	},
@@ -773,8 +773,8 @@ const struct mips_opcode mips_builtin_op
 {"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		0,		I3	},
 {"dvpe",    "",		0x41600001, 0xffffffff, TRAP,			0,		MT32	},
 {"dvpe",    "t",	0x41600001, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
-{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33|IOCT},
-{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33|IOCT},
+{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
 {"emt",     "",		0x41600be1, 0xffffffff, TRAP,			0,		MT32	},
 {"emt",     "t",	0x41600be1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
 {"eret",    "",         0x42000018, 0xffffffff, NODS,      		0,		I3_32	},
@@ -858,10 +858,10 @@ const struct mips_opcode mips_builtin_op
 {"l.d",     "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	}, /* ldc1 */
 {"l.d",     "T,o(b)",	0,    (int) M_L_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"l.d",     "T,A(b)",	0,    (int) M_L_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
-{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2	},
-{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
-{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2	},
+{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2,		IOCT|IOCTP|IOCT2	},
 {"ldl",	    "t,o(b)",	0x68000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
 {"ldl",	    "t,A(b)",	0,    (int) M_LDL_AB,	INSN_MACRO,		0,		I3	},
 {"ldr",	    "t,o(b)",	0x6c000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
@@ -884,18 +884,18 @@ const struct mips_opcode mips_builtin_op
 {"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I5_33|N55},
 {"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		0,		I1	},
-{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1	},
+{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"lwc1",    "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "E,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
 {"lwc1",    "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"lwc1",    "E,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"l.s",     "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	}, /* lwc1 */
 {"l.s",     "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1	},
-{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
-{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1	},
+{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"lwl",     "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lwl",     "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I1	},
 {"lcache",  "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I2	}, /* same */
@@ -958,20 +958,20 @@ const struct mips_opcode mips_builtin_op
 {"mftc0",   "d,E,H",	0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
 {"mftc1",   "d,T",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
 {"mftc1",   "d,E",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
-{"mftc2",   "d,E",	0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mftc2",   "d,E",	0x41000024, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"mftdsp",  "d",	0x41100021, 0xffff07ff, TRAP|WR_d,		0,		MT32	},
 {"mftgpr",  "d,t",	0x41000020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mfthc1",  "d,T",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
 {"mfthc1",  "d,E",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
-{"mfthc2",  "d,E",	0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mfthc2",  "d,E",	0x41000034, 0xffe007ff,	TRAP|LCD|WR_d|RD_C2,	0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"mfthi",   "d",	0x41010021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mfthi",   "d,*",	0x41010021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d",	0x41000021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftlo",   "d,*",	0x41000021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
 {"mftr",    "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d,		0,		MT32	},
-{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1|IOCT	},
-{"mfc0",    "t,+D",     0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
-{"mfc0",    "t,G,H",    0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32|IOCT},
+{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"mfc0",    "t,+D",0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
+{"mfc0",    "t,G,H",	0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
 {"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
@@ -1050,9 +1050,9 @@ const struct mips_opcode mips_builtin_op
 {"msubu",   "7,s,t",	0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D32	},
 {"mtpc",    "t,P",	0x4080c801, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
 {"mtps",    "t,P",	0x4080c800, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
-{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1|IOCT	},
-{"mtc0",    "t,+D",     0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
-{"mtc0",    "t,G,H",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32|IOCT},
+{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1	},
+{"mtc0",    "t,+D",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
+{"mtc0",    "t,G,H",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
 {"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
@@ -1078,14 +1078,14 @@ const struct mips_opcode mips_builtin_op
 {"mttc0",   "t,G,H",	0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
 {"mttc1",   "t,S",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
 {"mttc1",   "t,G",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
-{"mttc2",   "t,g",	0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mttc2",   "t,g",	0x41800024, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"mttacx",  "t",	0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttacx",  "t,&",	0x41801021, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttdsp",  "t",	0x41808021, 0xffe0ffff, TRAP|RD_t,		0,		MT32	},
 {"mttgpr",  "t,d",	0x41800020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
 {"mtthc1",  "t,S",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
 {"mtthc1",  "t,G",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
-{"mtthc2",  "t,g",	0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mtthc2",  "t,g",	0x41800034, 0xffe007ff,	TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32,		IOCT|IOCTP|IOCT2	},
 {"mtthi",   "t",	0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mtthi",   "t,&",	0x41800821, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
 {"mttlo",   "t",	0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
@@ -1303,10 +1303,10 @@ const struct mips_opcode mips_builtin_op
 {"sdc1",    "E,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"sdc1",    "T,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
 {"sdc1",    "E,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2	},
-{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000, SM|RD_C2|RD_b,		0,		I2	},
-{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2	},
-{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000, SM|RD_C3|RD_b,		0,		I2	},
-{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2	},
+{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I2,		IOCT|IOCTP|IOCT2	},
+{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2,		IOCT|IOCTP|IOCT2	},
 {"s.d",     "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
 {"s.d",     "T,o(b)",	0,    (int) M_S_DOB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
 {"s.d",     "T,A(b)",	0,    (int) M_S_DAB,	INSN_MACRO,		INSN2_M_FP_D,	I1	},
@@ -1428,18 +1428,18 @@ const struct mips_opcode mips_builtin_op
 {"swapw",   "t,b",	0x70000014, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapwu",  "t,b",	0x70000015, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"swapd",   "t,b",	0x70000016, 0xfc00ffff, SM|RD_t|WR_t|RD_b,	0,		XLR	},
-{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1	},
-{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1	},
+{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"swc1",    "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "E,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
 {"swc1",    "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"swc1",    "E,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"s.s",     "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	}, /* swc1 */
 {"s.s",     "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1	},
-{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1	},
-{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1	},
-{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1	},
+{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"swl",     "t,o(b)",	0xa8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"swl",     "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I1	},
 {"scache",  "t,o(b)",	0xa8000000, 0xfc000000,	RD_t|RD_b,		0,		I2	}, /* same */
@@ -1618,47 +1618,47 @@ const struct mips_opcode mips_builtin_op
 
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
-{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
-{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
-{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
+{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
+{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"dmfc2",   "t,i",	0x48200000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		IOCT	},
-{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3	},
-{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64	},
+{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3,		IOCT|IOCTP|IOCT2	},
+{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64,		IOCT|IOCTP|IOCT2	},
 {"dmtc2",   "t,i",	0x48a00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		IOCT	},
-{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3	},
-{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64	},
-{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
-{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32	},
-{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33	},
-{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1	},
-{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32	},
-{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
-{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
+{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3,		IOCT|IOCTP|IOCT2	},
+{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64,		IOCT|IOCTP|IOCT2	},
+{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33,		IOCT|IOCTP|IOCT2	},
+{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33,		IOCT|IOCTP|IOCT2	},
+{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33,		IOCT|IOCTP|IOCT2	},
+{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1,		IOCT|IOCTP|IOCT2	},
+{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32,		IOCT|IOCTP|IOCT2	},
+{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
+{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
+{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
 
 /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X 
    instructions, so they are here for the latters to take precedence.  */
-{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
-{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 	0,		I3	},
-{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC,	0,		I3	},
-{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
-{"mfc3",    "t,G,H",    0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 	0,		I32     },
-{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1	},
-{"mtc3",    "t,G,H",    0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   0,		I32     },
+{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
+{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
+{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I3,		IOCT|IOCTP|IOCT2	},
+{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I3,		IOCT|IOCTP|IOCT2	},
+{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"mfc3",    "t,G,H",	0x4c000000, 0xffe007f8,	LCD|WR_t|RD_C3,		0,		I32,		IOCT|IOCTP|IOCT2	},
+{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1,		IOCT|IOCTP|IOCT2	},
+{"mtc3",    "t,G,H",	0x4c800000, 0xffe007f8,	COD|RD_t|WR_C3|WR_CC,	0,		I32,		IOCT|IOCTP|IOCT2	},
 
   /* Conflicts with the 4650's "mul" instruction.  Nobody's using the
      4010 any more, so move this insn out of the way.  If the object
@@ -1945,10 +1945,10 @@ const struct mips_opcode mips_builtin_op
 {"dpsqx_s.w.ph", "7,s,t", 0x7c000670, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 {"dpsqx_sa.w.ph", "7,s,t", 0x7c0006f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
 /* Move bc0* after mftr and mttr to avoid opcode collision.  */
-{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
-{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
-{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
+{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
 /* ST Microelectronics Loongson-2E and -2F.  */
 {"mult.g",	"d,s,t",	0x7c000018,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2E	},
 {"mult.g",	"d,s,t",	0x70000010,	0xfc0007ff,	RD_s|RD_t|WR_d,	0,	IL2F	},
@@ -2108,14 +2108,14 @@ const struct mips_opcode mips_builtin_op
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
    disassembler recognizes more specific versions first.  */
-{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1	},
+{"c0",      "C",	0x42000000, 0xfe000000,	CP,			0,		I1,		IOCT|IOCTP|IOCT2	},
 {"c1",      "C",	0x46000000, 0xfe000000,	FP_S,			0,		I1	},
-{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1	},
-{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1	},
-{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1	},
+{"c2",      "C",	0x4a000000, 0xfe000000,	CP,			0,		I1,		IOCT|IOCTP|IOCT2	},
+{"c3",      "C",	0x4e000000, 0xfe000000,	CP,			0,		I1,		IOCT|IOCTP|IOCT2	},
+{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
-{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1	},
-{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1	}
+{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 };
 
 #define MIPS_NUM_OPCODES \

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2012-08-10 11:08     ` Maciej W. Rozycki
@ 2012-08-12 18:33       ` Richard Sandiford
  2012-08-13 14:56         ` Maciej W. Rozycki
  2013-06-17 11:51       ` Alan Modra
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2012-08-12 18:33 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: David Daney, Andrew Pinski, binutils

"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> On Thu, 17 Nov 2011, Richard Sandiford wrote:
>
>> > @@ -830,37 +833,38 @@ static const unsigned int mips_isa_table
>> >     ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
>> >     test, or zero if no CPU specific ISA test is desired.  */
>> >  
>> > -#define OPCODE_IS_MEMBER(insn, isa, cpu)				\
>> > -    (((isa & INSN_ISA_MASK) != 0                                        \
>> > -      && ((insn)->membership & INSN_ISA_MASK) != 0                      \
>> > -      && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>                \
>> > -           (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)       \
>> > -     || ((isa & ~INSN_ISA_MASK)                                         \
>> > -          & ((insn)->membership & ~INSN_ISA_MASK)) != 0                 \
>> > -     || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
>> > -     || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
>> > -     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
>> > -     || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
>> > -     || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
>> > -     || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
>> > -     || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	\
>> > -	  || cpu == CPU_R16000)						\
>> > -	 && ((insn)->membership & INSN_10000) != 0)			\
>> > -     || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	\
>> > -     || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	\
>> > -     || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	\
>> > -     || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	\
>> > -     || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	\
>> > -     || (cpu == CPU_LOONGSON_2E                                         \
>> > -         && ((insn)->membership & INSN_LOONGSON_2E) != 0)               \
>> > -     || (cpu == CPU_LOONGSON_2F                                         \
>> > -         && ((insn)->membership & INSN_LOONGSON_2F) != 0)               \
>> > -     || (cpu == CPU_LOONGSON_3A                                         \
>> > -         && ((insn)->membership & INSN_LOONGSON_3A) != 0)               \
>> > -     || (cpu == CPU_OCTEON						\
>> > -	 && ((insn)->membership & INSN_OCTEON) != 0)			\
>> > -     || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)        \
>> > -     || 0)	/* Please keep this term for easier source merging.  */
>> > +#define OPCODE_IS_MEMBER(insn, isa, cpu)				    \
>> > +    ((((isa & INSN_ISA_MASK) != 0					    \
>> > +       && ((insn)->membership & INSN_ISA_MASK) != 0			    \
>> > +       && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >>		    \
>> > +	    (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0)	    \
>> > +      || ((isa & ~INSN_ISA_MASK)					    \
>> > +	   & ((insn)->membership & ~INSN_ISA_MASK)) != 0		    \
>> > +      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	    \
>> > +      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	    \
>> > +      || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	    \
>> > +      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	    \
>> > +      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	    \
>> > +      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	    \
>> > +      || ((cpu == CPU_R10000 || cpu == CPU_R12000 || cpu == CPU_R14000	    \
>> > +	   || cpu == CPU_R16000)					    \
>> > +	  && ((insn)->membership & INSN_10000) != 0)			    \
>> > +      || (cpu == CPU_SB1 && ((insn)->membership & INSN_SB1) != 0)	    \
>> > +      || (cpu == CPU_R4111 && ((insn)->membership & INSN_4111) != 0)	    \
>> > +      || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0)	    \
>> > +      || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0)	    \
>> > +      || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0)	    \
>> > +      || (cpu == CPU_LOONGSON_2E					    \
>> > +	  && ((insn)->membership & INSN_LOONGSON_2E) != 0)		    \
>> > +      || (cpu == CPU_LOONGSON_2F					    \
>> > +	  && ((insn)->membership & INSN_LOONGSON_2F) != 0)		    \
>> > +      || (cpu == CPU_LOONGSON_3A					    \
>> > +	  && ((insn)->membership & INSN_LOONGSON_3A) != 0)		    \
>> > +      || (cpu == CPU_OCTEON && ((insn)->membership & INSN_OCTEON) != 0)    \
>> > +      || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0)	    \
>> > +      || 0)	/* Please keep this term for easier source merging.  */	    \
>> > +     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	    \
>> 
>> Looks like a typo for "((insn)->exclusions & INSN_OCTEON) == 0".
>
>  Hmm, where's the typo?  That's supposed to be true as long as the CPU is 
> other than Octeon or the Octeon exclusion bit is zero.  Did I get that 
> wrong?

The typo is in the last line I quoted:

>> > +     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

CPU_OCTEON is an enum value (6501), not a bitmask value.  As I say,
it looked like it should be "((insn)->exclusions & INSN_OCTEON) == 0"
instead.

Patch is OK.

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2012-08-12 18:33       ` Richard Sandiford
@ 2012-08-13 14:56         ` Maciej W. Rozycki
  0 siblings, 0 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2012-08-13 14:56 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: David Daney, Andrew Pinski, binutils

On Sun, 12 Aug 2012, Richard Sandiford wrote:

> >  Hmm, where's the typo?  That's supposed to be true as long as the CPU is 
> > other than Octeon or the Octeon exclusion bit is zero.  Did I get that 
> > wrong?
> 
> The typo is in the last line I quoted:
> 
> >> > +     && ((cpu != CPU_OCTEON || ((insn)->exclusions & CPU_OCTEON) == 0)	
>                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> CPU_OCTEON is an enum value (6501), not a bitmask value.  As I say,
> it looked like it should be "((insn)->exclusions & INSN_OCTEON) == 0"
> instead.

 Awww!

> Patch is OK.

 And now in, thanks.

  Maciej

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2012-08-10 11:08     ` Maciej W. Rozycki
  2012-08-12 18:33       ` Richard Sandiford
@ 2013-06-17 11:51       ` Alan Modra
  2013-06-17 15:18         ` Maciej W. Rozycki
  1 sibling, 1 reply; 14+ messages in thread
From: Alan Modra @ 2013-06-17 11:51 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

On Fri, Aug 10, 2012 at 12:07:11PM +0100, Maciej W. Rozycki wrote:
> +micromips-opc.lo: micromips-opc.c
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +
> +mips-opc.lo: mips-opc.c
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +
> +mips16-opc.lo: mips16-opc.c
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +

This patch resulted in no dependencies being generated for the mips
opcode files, causing my regression tests to fail spectacularly from
time to time.  I finally got around to looking into the problem.

	* Makefile.am (mips-opc.lo): Add rules to create automatic
	dependency files.  Pass archdefs.
	(micromips-opc.lo, mips16-opc.lo): Likewise.
	* Makefile.in: Regenerate.

Index: opcodes/Makefile.am
===================================================================
RCS file: /cvs/src/src/opcodes/Makefile.am,v
retrieving revision 1.172
diff -u -p -r1.172 Makefile.am
--- opcodes/Makefile.am	6 Feb 2013 23:22:25 -0000	1.172
+++ opcodes/Makefile.am	17 Jun 2013 11:06:21 -0000
@@ -573,13 +573,43 @@ $(srcdir)/rl78-decode.c: @MAINT@ $(srcdi
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rl78-decode.opc > $(srcdir)/rl78-decode.c
 
 micromips-opc.lo: micromips-opc.c
-	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+if am__fastdepCC
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
+	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
+	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
+endif
 
 mips-opc.lo: mips-opc.c
-	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+if am__fastdepCC
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
+	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
+	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
+endif
 
 mips16-opc.lo: mips16-opc.c
-	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
+if am__fastdepCC
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
+	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
+	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
+endif
 
 $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
 	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2013-06-17 11:51       ` Alan Modra
@ 2013-06-17 15:18         ` Maciej W. Rozycki
  2013-06-17 19:53           ` Richard Sandiford
  2013-06-18  0:27           ` Alan Modra
  0 siblings, 2 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2013-06-17 15:18 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

On Mon, 17 Jun 2013, Alan Modra wrote:

> > +micromips-opc.lo: micromips-opc.c
> > +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> > +
> > +mips-opc.lo: mips-opc.c
> > +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> > +
> > +mips16-opc.lo: mips16-opc.c
> > +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> > +
> 
> This patch resulted in no dependencies being generated for the mips
> opcode files, causing my regression tests to fail spectacularly from
> time to time.  I finally got around to looking into the problem.

 Oops, sorry about causing this regression -- I didn't notice it -- and 
thanks for addressing it.

> 	* Makefile.am (mips-opc.lo): Add rules to create automatic
> 	dependency files.  Pass archdefs.
> 	(micromips-opc.lo, mips16-opc.lo): Likewise.
> 	* Makefile.in: Regenerate.
> 
> Index: opcodes/Makefile.am
> ===================================================================
> RCS file: /cvs/src/src/opcodes/Makefile.am,v
> retrieving revision 1.172
> diff -u -p -r1.172 Makefile.am
> --- opcodes/Makefile.am	6 Feb 2013 23:22:25 -0000	1.172
> +++ opcodes/Makefile.am	17 Jun 2013 11:06:21 -0000
> @@ -573,13 +573,43 @@ $(srcdir)/rl78-decode.c: @MAINT@ $(srcdi
>  	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rl78-decode.opc > $(srcdir)/rl78-decode.c
>  
>  micromips-opc.lo: micromips-opc.c
> -	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +if am__fastdepCC
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
> +	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
> +	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
> +else
> +if AMDEP
> +	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
> +	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
> +endif
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
> +endif
>  
>  mips-opc.lo: mips-opc.c
> -	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +if am__fastdepCC
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
> +	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
> +	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
> +else
> +if AMDEP
> +	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
> +	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
> +endif
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
> +endif
>  
>  mips16-opc.lo: mips16-opc.c
> -	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ $<
> +if am__fastdepCC
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) \
> +	  -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ @archdefs@ $<
> +	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
> +else
> +if AMDEP
> +	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
> +	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
> +endif
> +	$(LTCOMPILE) $(NO_WMISSING_FIELD_INITIALIZERS) -c -o $@ @archdefs@ $<
> +endif
>  
>  $(srcdir)/rx-decode.c: @MAINT@ $(srcdir)/rx-decode.opc opc2c$(EXEEXT_FOR_BUILD)
>  	./opc2c$(EXEEXT_FOR_BUILD) $(srcdir)/rx-decode.opc > $(srcdir)/rx-decode.c

 Hmm, this looks horribly tied to automake's internals to me and I am 
afraid is bound to break as soon as automake maintainers decide to change 
how the rules are generated.  I know that this is going to be a pain, but 
I wonder if it could be rewritten in a way that is portable across 
automake versions, that is only relying on automake's published interface.

 There is a way to request per-object compilation flags described in the 
`Per-Object Flags Emulation' section of the automake manual.  It involves 
auxiliary convenience libraries (aka `ar' archives) and I used it 
successfully in the past, albeit with program targets only rather than 
libtool libraries.  I do hope with little effort that can be adapted for 
the latter case too.

 This looks a bit convoluted, and frankly I'd prefer if automake supported 
true per-object flags with no need to resort to hacks like this, but there 
you go.  The benefit would be no need to check the rules against generated 
ones with each automake upgrade, that is less maintenance burden -- and 
the maintenance of our autoconf scriptery has already proved tough even 
without that.

 Do you want me to check this alternative or would you prefer to do this 
yourself?

  Maciej

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2013-06-17 15:18         ` Maciej W. Rozycki
@ 2013-06-17 19:53           ` Richard Sandiford
  2013-06-17 22:30             ` Maciej W. Rozycki
  2013-06-18  0:27           ` Alan Modra
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2013-06-17 19:53 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Alan Modra, binutils

"Maciej W. Rozycki" <macro@codesourcery.com> writes:
>  This looks a bit convoluted, and frankly I'd prefer if automake supported 
> true per-object flags with no need to resort to hacks like this, but there 
> you go.  The benefit would be no need to check the rules against generated 
> ones with each automake upgrade, that is less maintenance burden -- and 
> the maintenance of our autoconf scriptery has already proved tough even 
> without that.
>
>  Do you want me to check this alternative or would you prefer to do this 
> yourself?

What do you think about explicitly initialising each field after all?
I can easily repurpose the ASE-checking script to do that.

I understand the original reason for having optional fields, but the
workaround is beginning to feel a bit convoluted.  There's also more
room for confusion than there was originally, now that we have the
ASE field too.

Thanks,
Richard



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2013-06-17 19:53           ` Richard Sandiford
@ 2013-06-17 22:30             ` Maciej W. Rozycki
  0 siblings, 0 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2013-06-17 22:30 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Alan Modra, binutils

On Mon, 17 Jun 2013, Richard Sandiford wrote:

> >  This looks a bit convoluted, and frankly I'd prefer if automake supported 
> > true per-object flags with no need to resort to hacks like this, but there 
> > you go.  The benefit would be no need to check the rules against generated 
> > ones with each automake upgrade, that is less maintenance burden -- and 
> > the maintenance of our autoconf scriptery has already proved tough even 
> > without that.
> >
> >  Do you want me to check this alternative or would you prefer to do this 
> > yourself?
> 
> What do you think about explicitly initialising each field after all?
> I can easily repurpose the ASE-checking script to do that.

 Great!  I'm fine with that, sure.  While at it we could add pinfo3 too -- 
some microMIPS instructions (offhand: ALNV.PS ;) ) will benefit from more 
accurate data dependency tracking.

> I understand the original reason for having optional fields, but the
> workaround is beginning to feel a bit convoluted.  There's also more
> room for confusion than there was originally, now that we have the
> ASE field too.

 Agreed.  What I think was important was not to add an extra field while 
rewriting the opcode table at the same time -- that would obfuscate the 
change itself.

  Maciej

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2013-06-17 15:18         ` Maciej W. Rozycki
  2013-06-17 19:53           ` Richard Sandiford
@ 2013-06-18  0:27           ` Alan Modra
  2013-06-24 14:28             ` Maciej W. Rozycki
  1 sibling, 1 reply; 14+ messages in thread
From: Alan Modra @ 2013-06-18  0:27 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

On Mon, Jun 17, 2013 at 04:18:45PM +0100, Maciej W. Rozycki wrote:
> > 	* Makefile.am (mips-opc.lo): Add rules to create automatic
> > 	dependency files.  Pass archdefs.
> > 	(micromips-opc.lo, mips16-opc.lo): Likewise.
> > 	* Makefile.in: Regenerate.
> 
>  Hmm, this looks horribly tied to automake's internals to me and I am 
> afraid is bound to break as soon as automake maintainers decide to change 
> how the rules are generated.  I know that this is going to be a pain, but 
> I wonder if it could be rewritten in a way that is portable across 
> automake versions, that is only relying on automake's published interface.

I used more or less the same rules as Ralf Wildenhues added for the
binutils project back in 2009-08, when he fixed a lot of Makefile.am
issues for us.  Judging from his activity in the automake project, I'd
say he knew a thing or two about automake, so I personally would be a
little cautious about using some other construct!

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] MIPS: Opcode membership proposal
  2013-06-18  0:27           ` Alan Modra
@ 2013-06-24 14:28             ` Maciej W. Rozycki
  0 siblings, 0 replies; 14+ messages in thread
From: Maciej W. Rozycki @ 2013-06-24 14:28 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

On Tue, 18 Jun 2013, Alan Modra wrote:

> > > 	* Makefile.am (mips-opc.lo): Add rules to create automatic
> > > 	dependency files.  Pass archdefs.
> > > 	(micromips-opc.lo, mips16-opc.lo): Likewise.
> > > 	* Makefile.in: Regenerate.
> > 
> >  Hmm, this looks horribly tied to automake's internals to me and I am 
> > afraid is bound to break as soon as automake maintainers decide to change 
> > how the rules are generated.  I know that this is going to be a pain, but 
> > I wonder if it could be rewritten in a way that is portable across 
> > automake versions, that is only relying on automake's published interface.
> 
> I used more or less the same rules as Ralf Wildenhues added for the
> binutils project back in 2009-08, when he fixed a lot of Makefile.am
> issues for us.  Judging from his activity in the automake project, I'd
> say he knew a thing or two about automake, so I personally would be a
> little cautious about using some other construct!

 Fair enough, although for a change I'd be a little worried if a construct 
that is advertised as The Right One in the official manual was not going 
to be maintained across future versions.  FWIW, as Richard's offer to make 
all the initialisers complete throughout these files supersedes of course 
any alternatives discussed by us here.

  Maciej

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-06-24 14:28 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-18 12:55 [PATCH] MIPS: Opcode membership proposal Maciej W. Rozycki
2010-12-20 18:15 ` David Daney
2010-12-20 18:33   ` Andrew Pinski
2011-10-31 12:47 ` Maciej W. Rozycki
2011-11-17 18:45   ` Richard Sandiford
2012-08-10 11:08     ` Maciej W. Rozycki
2012-08-12 18:33       ` Richard Sandiford
2012-08-13 14:56         ` Maciej W. Rozycki
2013-06-17 11:51       ` Alan Modra
2013-06-17 15:18         ` Maciej W. Rozycki
2013-06-17 19:53           ` Richard Sandiford
2013-06-17 22:30             ` Maciej W. Rozycki
2013-06-18  0:27           ` Alan Modra
2013-06-24 14:28             ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).