This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] microMIPS: Branch swapping support


Hi Richard,

 Here's a regenerated version of branch swapping support.  Apart from 
adjusting to your recent rework of register use determination code I've 
made no changes to this piece and it should be functionally equivalent to 
the version originally submitted.  For a reference, I'm providing the 
original paragraph summarising the changes made here (actually some 
changes written to be made here were made by you or myself with some 
patches that have been committed now separately, but I don't think it 
makes sense to revise this text at this point):

- binutils-gas-umips-swap.diff -- branch delay slot scheduling support for 
  microMIPS code as the DWARF-2 line number adjustment fix I posted 
  earlier made it possible to enable it now.  We lacked some 
  infrastructure here, so I have added the necessary register dependencies 
  tests, as well as checks that we don't reorder something unsuitable into 
  a slot of a fixed size (in theory we could do this anyway and flip the 
  delay-slot-size bit in the branch or jump instruction output, but that's 
  not as easy as it would seem at this point of instruction processing, so 
  I left it as a future enhancement [FIXME]).  I believe we can't reorder 
  an ADDIUPC either as it would break offset calculation if a label at the 
  instruction was used (quite likely) that doesn't get moved with the 
  swap.

  I have split some of the combined register access flags so that we can 
  avoid false negatives and reorder some frequent instructions, such as 
  16-bit MOVEs.  Some of these flags actually turned out not to be 
  combined at all.  I have joined the MM and MN flags as they are always 
  used together (by MOVEP) and therefore need not be separate.  Given the 
  shortage of flags (I tried to avoid overloading) I have decided MD and 
  SP are the ones that can remain combined, the former because it's only 
  used to mark registers read with branches and these cannot be scheduled 
  into delay slots anyway, and the latter because the use of $sp as the 
  condition for branches is unusual.  I have split them syntactically by 
  the usage throughout the opcode table though, so making them separate in 
  the future will be as easy as updating <opcode/mips.h> and any 
  references in GAS.

 Note that the [FIXME] above still applies.

 No regressions for mips-sde-elf and mips-gnu-linux.  OK to apply?

2011-08-02  Maciej W. Rozycki  <macro@codesourcery.com>

	include/opcode/
	* mips.h (INSN_WRITE_GPR_S, INSN2_WRITE_GPR_MB): New macros.
	(INSN2_READ_GPR_MC, INSN2_READ_GPR_ME): Likewise.
	(INSN2_WRITE_GPR_MF, INSN2_READ_GPR_MG): Likewise.
	(INSN2_READ_GPR_MJ, INSN2_WRITE_GPR_MJ): Likewise.
	(INSN2_READ_GPR_MP, INSN2_WRITE_GPR_MP): Likewise.
	(INSN2_READ_GPR_MQ, INSN2_WRITE_GPR_MHI): Likewise.
	(INSN2_READ_GPR_MMN): Likewise.
	(INSN2_READ_FPR_D, INSN2_MOD_GPR_MD): Change the bit used.
	(INSN2_MOD_SP, INSN2_READ_GPR_31, INSN2_READ_GP): Likewise.
	(INSN2_READ_PC, INSN2_UNCOND_BRANCH): Likewise.
	(INSN2_COND_BRANCH): Likewise.
	(INSN2_WRITE_GPR_S, INSN2_MOD_GPR_MB): Remove macros.
	(INSN2_MOD_GPR_MC, INSN2_MOD_GPR_ME, INSN2_MOD_GPR_MF): Likewise.
	(INSN2_MOD_GPR_MG, INSN2_MOD_GPR_MJ, INSN2_MOD_GPR_MP): Likewise.
	(INSN2_MOD_GPR_MQ, INSN2_MOD_GPR_MHI): Likewise.
	(INSN2_MOD_GPR_MM, INSN2_MOD_GPR_MN): Likewise.

	gas/
	* config/tc-mips.c (gpr_mod_mask): Remove INSN2_MOD_GPR_MB,
	INSN2_MOD_GPR_MC, INSN2_MOD_GPR_ME, INSN2_MOD_GPR_MF,
	INSN2_MOD_GPR_MG, INSN2_MOD_GPR_MHI, INSN2_MOD_GPR_MJ,
	INSN2_MOD_GPR_MM, INSN2_MOD_GPR_MN, INSN2_MOD_GPR_MP and
	INSN2_MOD_GPR_MQ opcode register use checks.
	(gpr_read_mask): Add INSN2_READ_GPR_MC, INSN2_READ_GPR_ME
	INSN2_READ_GPR_MG, INSN2_READ_GPR_MJ, INSN2_READ_GPR_MMN,
	INSN2_READ_GPR_MP and INSN2_READ_GPR_MQ opcode register use 
	checks.
	(gpr_write_mask): Replace INSN2_WRITE_GPR_S opcode register 
	use flag with INSN_WRITE_GPR_S.  Add INSN2_WRITE_GPR_MB,
	INSN2_WRITE_GPR_MF, INSN2_WRITE_GPR_MHI, INSN2_WRITE_GPR_MJ
	and INSN2_WRITE_GPR_MP opcode register use checks.
	(can_swap_branch_p): Enable microMIPS branch swapping.
	(append_insn): Likewise.

	gas/testsuite/
	* gas/mips/micromips.d: Update according to changes to enable 
	microMIPS branch swapping.
	* gas/mips/micromips-trap.d: Likewise.
	* gas/mips/micromips@jal-svr4pic.d: Likewise.
	* gas/mips/micromips@loc-swap.d: Likewise.
	* gas/mips/micromips@loc-swap-dis.d: Likewise.

	opcodes/
	* micromips-opc.c (MOD_mb, MOD_mc, MOD_md): Remove macros.
	(MOD_me, MOD_mf, MOD_mg, MOD_mhi, MOD_mj, MOD_ml): Likewise.
	(MOD_mm, MOD_mn, MOD_mp, MOD_mq, MOD_sp): Likewise.
	(WR_mb, RD_mc, RD_md, WR_md, RD_me, WR_mf, RD_mg): New macros.
	(WR_mhi, RD_mj, WR_mj, RD_ml, RD_mmn, RD_mp, WR_mp): Likewise.
	(RD_mq, RD_sp, WR_sp): Likewise.
	(WR_s): Update macro.
	(micromips_opcodes): Update register use flags of: "addiu", 
	"addiupc", "addiur1sp", "addiur2", "addius5", "addiusp", "addu", 
	"and", "andi", "beq", "beqz", "bne", "bnez", "di", "ei", "j", 
	"jalr", "jalrs", "jr", "jraddiusp", "jrc", "lbu", "lhu", "li", 
	"lui", "lw", "lwm", "mfhi", "mflo", "move", "movep", "not",
	"nor", "or", "ori", "sb", "sh", "sll", "srl", "subu", "sw",
	"swm" and "xor" instructions.

  Maciej

binutils-gas-umips-swap.diff
Index: binutils-fsf-trunk-quilt/opcodes/micromips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/micromips-opc.c	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/micromips-opc.c	2011-08-02 18:07:59.000000000 +0100
@@ -34,26 +34,29 @@
 /* For 16-bit/32-bit microMIPS instructions.  They are used in pinfo2.  */
 #define UBR	INSN2_UNCOND_BRANCH
 #define CBR	INSN2_COND_BRANCH
-#define MOD_mb	INSN2_MOD_GPR_MB
-#define MOD_mc	INSN2_MOD_GPR_MC
-#define MOD_md	INSN2_MOD_GPR_MD
-#define MOD_me	INSN2_MOD_GPR_ME
-#define MOD_mf	INSN2_MOD_GPR_MF
-#define MOD_mg	INSN2_MOD_GPR_MG
-#define MOD_mhi	INSN2_MOD_GPR_MHI
-#define MOD_mj	INSN2_MOD_GPR_MJ
-#define MOD_ml	MOD_mc	/* Reuse, since the bit position is the same.  */
-#define MOD_mm	INSN2_MOD_GPR_MM
-#define MOD_mn	INSN2_MOD_GPR_MN
-#define MOD_mp	INSN2_MOD_GPR_MP
-#define MOD_mq	INSN2_MOD_GPR_MQ
-#define MOD_sp	INSN2_MOD_SP
+#define WR_mb	INSN2_WRITE_GPR_MB
+#define RD_mc	INSN2_READ_GPR_MC
+#define RD_md	INSN2_MOD_GPR_MD
+#define WR_md	INSN2_MOD_GPR_MD
+#define RD_me	INSN2_READ_GPR_ME
+#define WR_mf	INSN2_WRITE_GPR_MF
+#define RD_mg	INSN2_READ_GPR_MG
+#define WR_mhi	INSN2_WRITE_GPR_MHI
+#define RD_mj	INSN2_READ_GPR_MJ
+#define WR_mj	INSN2_WRITE_GPR_MJ
+#define RD_ml	RD_mc	/* Reuse, since the bit position is the same.  */
+#define RD_mmn	INSN2_READ_GPR_MMN
+#define RD_mp	INSN2_READ_GPR_MP
+#define WR_mp	INSN2_WRITE_GPR_MP
+#define RD_mq	INSN2_READ_GPR_MQ
+#define RD_sp	INSN2_MOD_SP
+#define WR_sp	INSN2_MOD_SP
 #define RD_31	INSN2_READ_GPR_31
 #define RD_gp	INSN2_READ_GP
 #define RD_pc	INSN2_READ_PC
 
 /* For 32-bit microMIPS instructions.  */
-#define WR_s	INSN2_WRITE_GPR_S	/* Used in pinfo2.  */
+#define WR_s	INSN_WRITE_GPR_S
 #define WR_d	INSN_WRITE_GPR_D
 #define WR_t	INSN_WRITE_GPR_T
 #define WR_31	INSN_WRITE_GPR_31
@@ -110,7 +113,7 @@ const struct mips_opcode micromips_opcod
 {"ssnop",   "",		0x00000800, 0xffffffff,	0,			INSN2_ALIAS,	I1	}, /* sll */
 {"ehb",     "",		0x00001800, 0xffffffff,	0,			INSN2_ALIAS,	I1	}, /* sll */
 {"pause",   "",		0x00002800, 0xffffffff,	0,			INSN2_ALIAS,	I1	}, /* sll */
-{"li",      "md,mI",	    0xec00,     0xfc00,	0,			MOD_md,		I1	},
+{"li",      "md,mI",	    0xec00,     0xfc00,	0,			WR_md,		I1	},
 {"li",      "t,j",	0x30000000, 0xfc1f0000,	WR_t,			INSN2_ALIAS,	I1	}, /* addiu */
 {"li",      "t,i",	0x50000000, 0xfc1f0000,	WR_t,			INSN2_ALIAS,	I1	}, /* ori */
 #if 0
@@ -119,7 +122,7 @@ const struct mips_opcode micromips_opcod
 #endif
 {"li",      "t,I",	0,    (int) M_LI,	INSN_MACRO,		0,		I1	},
 {"move",    "d,s",	0,    (int) M_MOVE,	INSN_MACRO,		0,		I1	},
-{"move",    "mp,mj",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	},
+{"move",    "mp,mj",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	},
 {"move",    "d,s",	0x58000150, 0xffe007ff,	WR_d|RD_s,		INSN2_ALIAS,	I3	}, /* daddu */
 {"move",    "d,s",	0x00000150, 0xffe007ff,	WR_d|RD_s,		INSN2_ALIAS,	I1	}, /* addu */
 {"move",    "d,s",	0x00000290, 0xffe007ff,	WR_d|RD_s,		INSN2_ALIAS,	I1	}, /* or */
@@ -140,31 +143,31 @@ const struct mips_opcode micromips_opcod
 {"add.s",   "D,V,T",	0x54000030, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
 {"add.ps",  "D,V,T",	0x54000230, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
 {"addi",    "t,r,j",	0x10000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
-{"addiu",   "mp,mj,mZ",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
-{"addiu",   "md,ms,mW",	    0x6c01,     0xfc01,	0,			MOD_md|MOD_sp,	I1	}, /* addiur1sp */
-{"addiu",   "md,mc,mB",	    0x6c00,     0xfc01,	0,			MOD_md|MOD_mc,	I1	}, /* addiur2 */
-{"addiu",   "ms,mt,mY",	    0x4c01,     0xfc01,	0,			MOD_sp,		I1	}, /* addiusp */
-{"addiu",   "mp,mt,mX",	    0x4c00,     0xfc01,	0,			MOD_mp,		I1	}, /* addius5 */
-{"addiu",   "mb,mr,mQ",	0x78000000, 0xfc000000,	0,			MOD_mb|RD_pc,	I1	}, /* addiupc */
+{"addiu",   "mp,mj,mZ",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
+{"addiu",   "md,ms,mW",	    0x6c01,     0xfc01,	0,			WR_md|RD_sp,	I1	}, /* addiur1sp */
+{"addiu",   "md,mc,mB",	    0x6c00,     0xfc01,	0,			WR_md|RD_mc,	I1	}, /* addiur2 */
+{"addiu",   "ms,mt,mY",	    0x4c01,     0xfc01,	0,			WR_sp|RD_sp,		I1	}, /* addiusp */
+{"addiu",   "mp,mt,mX",	    0x4c00,     0xfc01,	0,			WR_mp|RD_mp,		I1	}, /* addius5 */
+{"addiu",   "mb,mr,mQ",	0x78000000, 0xfc000000,	0,			WR_mb|RD_pc,	I1	}, /* addiupc */
 {"addiu",   "t,r,j",	0x30000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
-{"addiupc", "mb,mQ",	0x78000000, 0xfc000000,	0,			MOD_mb|RD_pc,	I1	},
-{"addiur1sp", "md,mW",	    0x6c01,     0xfc01,	0,			MOD_md|MOD_sp,	I1	},
-{"addiur2", "md,mc,mB",	    0x6c00,     0xfc01,	0,			MOD_md|MOD_mc,	I1	},
-{"addiusp", "mY",	    0x4c01,     0xfc01,	0,			MOD_sp,		I1	},
-{"addius5", "mp,mX",	    0x4c00,     0xfc01,	0,			MOD_mp,		I1	},
-{"addu",    "mp,mj,mz",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
-{"addu",    "mp,mz,mj",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
-{"addu",    "md,me,ml",	    0x0400,     0xfc01,	0,			MOD_md|MOD_me|MOD_ml,	I1	},
+{"addiupc", "mb,mQ",	0x78000000, 0xfc000000,	0,			WR_mb|RD_pc,	I1	},
+{"addiur1sp", "md,mW",	    0x6c01,     0xfc01,	0,			WR_md|RD_sp,	I1	},
+{"addiur2", "md,mc,mB",	    0x6c00,     0xfc01,	0,			WR_md|RD_mc,	I1	},
+{"addiusp", "mY",	    0x4c01,     0xfc01,	0,			WR_sp|RD_sp,		I1	},
+{"addius5", "mp,mX",	    0x4c00,     0xfc01,	0,			WR_mp|RD_mp,		I1	},
+{"addu",    "mp,mj,mz",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
+{"addu",    "mp,mz,mj",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
+{"addu",    "md,me,ml",	    0x0400,     0xfc01,	0,			WR_md|RD_me|RD_ml,	I1	},
 {"addu",    "d,v,t",	0x00000150, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"addu",    "t,r,I",	0,    (int) M_ADDU_I,	INSN_MACRO,		0,		I1	},
 /* We have no flag to mark the read from "y", so we use TRAP to disable
    delay slot scheduling of ALNV.PS altogether.  */
 {"alnv.ps", "D,V,T,y",	0x54000019, 0xfc00003f,	TRAP|WR_D|RD_S|RD_T|FP_D, 0,		I1	},
-{"and",     "mf,mt,mg",	    0x4480,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
-{"and",     "mf,mg,mx",	    0x4480,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
+{"and",     "mf,mt,mg",	    0x4480,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
+{"and",     "mf,mg,mx",	    0x4480,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
 {"and",     "d,v,t",	0x00000250, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"and",     "t,r,I",	0,    (int) M_AND_I,	INSN_MACRO,		0,		I1	},
-{"andi",    "md,mc,mC",	    0x2c00,     0xfc00,	0,			MOD_md|MOD_mc,	I1	},
+{"andi",    "md,mc,mC",	    0x2c00,     0xfc00,	0,			WR_md|RD_mc,	I1	},
 {"andi",    "t,r,i",	0xd0000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
 /* b is at the top of the table.  */
 /* bal is at the top of the table.  */
@@ -184,12 +187,12 @@ const struct mips_opcode micromips_opcod
 {"bc2t",    "N,p",	0x42a00000, 0xffe30000,	CBD|RD_CC,		0,		I1	},
 {"bc2tl",   "p",	0,    (int) M_BC2TL,	INSN_MACRO,		0,		I1	},
 {"bc2tl",   "N,p",	0,    (int) M_BC2TL,	INSN_MACRO,		0,		I1	},
-{"beqz",    "md,mE",	    0x8c00,     0xfc00,	CBD,			MOD_md,		I1	},
+{"beqz",    "md,mE",	    0x8c00,     0xfc00,	CBD,			RD_md,		I1	},
 {"beqz",    "s,p",	0x94000000, 0xffe00000,	CBD|RD_s,		0,		I1	},
 {"beqzc",   "s,p",	0x40e00000, 0xffe00000,	NODS|RD_s,		CBR,		I1	},
 {"beqzl",   "s,p",	0,    (int) M_BEQL,	INSN_MACRO,		0,		I1	},
-{"beq",     "md,mz,mE",	    0x8c00,     0xfc00,	CBD,			MOD_md,		I1	}, /* beqz */
-{"beq",     "mz,md,mE",	    0x8c00,     0xfc00,	CBD,			MOD_md,		I1	}, /* beqz */
+{"beq",     "md,mz,mE",	    0x8c00,     0xfc00,	CBD,			RD_md,		I1	}, /* beqz */
+{"beq",     "mz,md,mE",	    0x8c00,     0xfc00,	CBD,			RD_md,		I1	}, /* beqz */
 {"beq",     "s,t,p",	0x94000000, 0xfc000000,	CBD|RD_s|RD_t,		0,		I1	},
 {"beq",     "s,I,p",	0,    (int) M_BEQ_I,	INSN_MACRO,		0,		I1	},
 {"beql",    "s,t,p",	0,    (int) M_BEQL,	INSN_MACRO,		0,		I1	},
@@ -240,12 +243,12 @@ const struct mips_opcode micromips_opcod
 {"bltzal",  "s,p",	0x40200000, 0xffe00000,	CBD|RD_s|WR_31,		BD32,		I1	},
 {"bltzals", "s,p",	0x42200000, 0xffe00000,	CBD|RD_s|WR_31,		BD16,		I1	},
 {"bltzall", "s,p",	0,    (int) M_BLTZALL,	INSN_MACRO,		0,		I1	},
-{"bnez",    "md,mE",	    0xac00,     0xfc00,	CBD,			MOD_md,		I1	},
+{"bnez",    "md,mE",	    0xac00,     0xfc00,	CBD,			RD_md,		I1	},
 {"bnez",    "s,p",	0xb4000000, 0xffe00000,	CBD|RD_s,		0,		I1	},
 {"bnezc",   "s,p",	0x40a00000, 0xffe00000,	NODS|RD_s,		CBR,		I1	},
 {"bnezl",   "s,p",	0,    (int) M_BNEL,	INSN_MACRO,		0,		I1	},
-{"bne",     "md,mz,mE",	    0xac00,     0xfc00,	CBD,			MOD_md,		I1	}, /* bnez */
-{"bne",     "mz,md,mE",	    0xac00,     0xfc00,	CBD,			MOD_md,		I1	}, /* bnez */
+{"bne",     "md,mz,mE",	    0xac00,     0xfc00,	CBD,			RD_md,		I1	}, /* bnez */
+{"bne",     "mz,md,mE",	    0xac00,     0xfc00,	CBD,			RD_md,		I1	}, /* bnez */
 {"bne",     "s,t,p",	0xb4000000, 0xfc000000,	CBD|RD_s|RD_t,		0,		I1	},
 {"bne",     "s,I,p",	0,    (int) M_BNE_I,	INSN_MACRO,		0,		I1	},
 {"bnel",    "s,t,p",	0,    (int) M_BNEL,	INSN_MACRO,		0,		I1	},
@@ -405,8 +408,8 @@ const struct mips_opcode micromips_opcod
 {"ddivu",   "z,t",	0x5800bb3c, 0xfc1fffff,	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",      "",		0x0000477c, 0xffffffff,	RD_C0,			WR_s,		I1	},
-{"di",      "s",	0x0000477c, 0xffe0ffff,	RD_C0,			WR_s,		I1	},
+{"di",      "",		0x0000477c, 0xffffffff,	WR_s|RD_C0,		0,		I1	},
+{"di",      "s",	0x0000477c, 0xffe0ffff,	WR_s|RD_C0,		0,		I1	},
 {"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		0,		I3	},
 {"dins",    "t,r,+A,+B",0x5800000c, 0xfc00003f, WR_t|RD_s,		0,		I3	},
 {"dinsm",   "t,r,+A,+F",0x58000004, 0xfc00003f, WR_t|RD_s,		0,		I3	},
@@ -495,8 +498,8 @@ const struct mips_opcode micromips_opcod
 {"dsub",    "d,v,I",	0,    (int) M_DSUB_I,	INSN_MACRO,		0,		I3	},
 {"dsubu",   "d,v,t",	0x580001d0, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I3	},
 {"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		0,		I3	},
-{"ei",      "",		0x0000577c, 0xffffffff,	WR_C0,			WR_s,		I1	},
-{"ei",      "s",	0x0000577c, 0xffe0ffff,	WR_C0,			WR_s,		I1	},
+{"ei",      "",		0x0000577c, 0xffffffff,	WR_s|WR_C0,		0,		I1	},
+{"ei",      "s",	0x0000577c, 0xffe0ffff,	WR_s|WR_C0,		0,		I1	},
 {"eret",    "",		0x0000f37c, 0xffffffff,	NODS,			0,		I1	},
 {"ext",     "t,r,+A,+C", 0x0000002c, 0xfc00003f, WR_t|RD_s,		0,		I1	},
 {"floor.l.d", "T,V",	0x5400433b, 0xfc00ffff,	WR_T|RD_S|FP_D,		0,		I1	},
@@ -504,14 +507,14 @@ const struct mips_opcode micromips_opcod
 {"floor.w.d", "T,V",	0x54004b3b, 0xfc00ffff,	WR_T|RD_S|FP_S|FP_D,	0,		I1	},
 {"floor.w.s", "T,V",	0x54000b3b, 0xfc00ffff,	WR_T|RD_S|FP_S,		0,		I1	},
 {"ins",     "t,r,+A,+B", 0x0000000c, 0xfc00003f, WR_t|RD_s,		0,		I1	},
-{"jr",      "mj",	    0x4580,     0xffe0,	UBD,			MOD_mj,		I1	},
+{"jr",      "mj",	    0x4580,     0xffe0,	UBD,			RD_mj,		I1	},
 {"jr",      "s",	0x00000f3c, 0xffe0ffff,	UBD|RD_s,		BD32,		I1	}, /* jalr */
 {"jrs",     "s",	0x00004f3c, 0xffe0ffff,	UBD|RD_s,		BD16,		I1	}, /* jalrs */
-{"jraddiusp", "mP",	    0x4700,     0xffe0,	NODS,			UBR|RD_31|MOD_sp,	I1	},
-{"jrc",     "mj",	    0x45a0,     0xffe0,	NODS,			UBR|MOD_mj,		I1	},
+{"jraddiusp", "mP",	    0x4700,     0xffe0,	NODS,			UBR|RD_31|WR_sp|RD_sp,	I1	},
+{"jrc",     "mj",	    0x45a0,     0xffe0,	NODS,			UBR|RD_mj,		I1	},
 {"jr.hb",   "s",	0x00001f3c, 0xffe0ffff,	UBD|RD_s,		BD32,		I1	}, /* jalr.hb */
 {"jrs.hb",  "s",	0x00005f3c, 0xffe0ffff,	UBD|RD_s,		BD16,		I1	}, /* jalrs.hb */
-{"j",       "mj",	    0x4580,     0xffe0,	UBD,			MOD_mj,		I1	}, /* jr */
+{"j",       "mj",	    0x4580,     0xffe0,	UBD,			RD_mj,		I1	}, /* jr */
 {"j",       "s",	0x00000f3c, 0xffe0ffff,	UBD|RD_s,		BD32,		I1	}, /* jr */
 /* SVR4 PIC code requires special handling for j, so it must be a
    macro.  */
@@ -520,14 +523,14 @@ const struct mips_opcode micromips_opcod
    assembler, but will never match user input (because the line above
    will match first).  */
 {"j",       "a",	0xd4000000, 0xfc000000,	UBD,			0,		I1	},
-{"jalr",    "mj",	    0x45c0,     0xffe0,	UBD|WR_31,		MOD_mj|BD32,	I1	},
-{"jalr",    "my,mj",	    0x45c0,     0xffe0,	UBD|WR_31,		MOD_mj|BD32,	I1	},
+{"jalr",    "mj",	    0x45c0,     0xffe0,	UBD|WR_31,		RD_mj|BD32,	I1	},
+{"jalr",    "my,mj",	    0x45c0,     0xffe0,	UBD|WR_31,		RD_mj|BD32,	I1	},
 {"jalr",    "s",	0x03e00f3c, 0xffe0ffff,	UBD|RD_s|WR_t,		BD32,		I1	},
 {"jalr",    "t,s",	0x00000f3c, 0xfc00ffff,	UBD|RD_s|WR_t,		BD32,		I1	},
 {"jalr.hb", "s",	0x03e01f3c, 0xffe0ffff,	UBD|RD_s|WR_t,		BD32,		I1	},
 {"jalr.hb", "t,s",	0x00001f3c, 0xfc00ffff,	UBD|RD_s|WR_t,		BD32,		I1	},
-{"jalrs",   "mj",	    0x45e0,     0xffe0,	UBD|WR_31,		MOD_mj|BD16,	I1	},
-{"jalrs",   "my,mj",	    0x45e0,     0xffe0,	UBD|WR_31,		MOD_mj|BD16,	I1	},
+{"jalrs",   "mj",	    0x45e0,     0xffe0,	UBD|WR_31,		RD_mj|BD16,	I1	},
+{"jalrs",   "my,mj",	    0x45e0,     0xffe0,	UBD|WR_31,		RD_mj|BD16,	I1	},
 {"jalrs",   "s",	0x03e04f3c, 0xffe0ffff,	UBD|RD_s|WR_t,		BD16,		I1	},
 {"jalrs",   "t,s",	0x00004f3c, 0xfc00ffff,	UBD|RD_s|WR_t,		BD16,		I1	},
 {"jalrs.hb", "s",	0x03e05f3c, 0xffe0ffff,	UBD|RD_s|WR_t,		BD16,		I1	},
@@ -549,7 +552,7 @@ const struct mips_opcode micromips_opcod
 {"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		0,		I1	},
 {"lb",      "t,o(b)",	0x1c000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lb",      "t,A(b)",	0,    (int) M_LB_AB,	INSN_MACRO,		0,		I1	},
-{"lbu",     "md,mG(ml)",    0x0800,     0xfc00,	0,			MOD_md|MOD_ml,	I1	},
+{"lbu",     "md,mG(ml)",    0x0800,     0xfc00,	0,			WR_md|RD_ml,	I1	},
 {"lbu",     "t,o(b)",	0x14000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lbu",     "t,A(b)",	0,    (int) M_LBU_AB,	INSN_MACRO,		0,		I1	},
 {"lca",     "t,A(b)",	0,    (int) M_LCA_AB,	INSN_MACRO,		0,		I1	},
@@ -581,7 +584,7 @@ const struct mips_opcode micromips_opcod
 {"ldxc1",   "D,t(b)",	0x540000c8, 0xfc0007ff,	WR_D|RD_t|RD_b|FP_D,	0,		I1	},
 {"lh",      "t,o(b)",	0x3c000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lh",      "t,A(b)",	0,    (int) M_LH_AB,	INSN_MACRO,		0,		I1	},
-{"lhu",     "md,mH(ml)",    0x2800,     0xfc00,	0,			MOD_md|MOD_ml,	I1	},
+{"lhu",     "md,mH(ml)",    0x2800,     0xfc00,	0,			WR_md|RD_ml,	I1	},
 {"lhu",     "t,o(b)",	0x34000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lhu",     "t,A(b)",	0,    (int) M_LHU_AB,	INSN_MACRO,		0,		I1	},
 /* li is at the start of the table.  */
@@ -595,11 +598,11 @@ const struct mips_opcode micromips_opcod
 {"lld",     "t,~(b)",	0x60007000, 0xfc00f000,	RD_b|WR_t,		0,		I3	},
 {"lld",     "t,o(b)",	0,    (int) M_LLD_OB,	INSN_MACRO,		0,		I3	},
 {"lld",     "t,A(b)",	0,    (int) M_LLD_AB,	INSN_MACRO,		0,		I3	},
-{"lui",     "s,u",	0x41a00000, 0xffe00000,	0,			WR_s,		I1	},
+{"lui",     "s,u",	0x41a00000, 0xffe00000,	WR_s,			0,		I1	},
 {"luxc1",   "D,t(b)",	0x54000148, 0xfc0007ff,	WR_D|RD_t|RD_b|FP_D,	0,		I1	},
-{"lw",      "md,mJ(ml)",    0x6800,     0xfc00,	0,			MOD_md|MOD_ml,	I1	},
-{"lw",      "mp,mU(ms)",    0x4800,     0xfc00,	0,			MOD_mp|MOD_sp,	I1	}, /* lwsp */
-{"lw",      "md,mA(ma)",    0x6400,     0xfc00,	0,			MOD_md|RD_gp,	I1	}, /* lwgp */
+{"lw",      "md,mJ(ml)",    0x6800,     0xfc00,	0,			WR_md|RD_ml,	I1	},
+{"lw",      "mp,mU(ms)",    0x4800,     0xfc00,	0,			WR_mp|RD_sp,	I1	}, /* lwsp */
+{"lw",      "md,mA(ma)",    0x6400,     0xfc00,	0,			WR_md|RD_gp,	I1	}, /* lwgp */
 {"lw",      "t,o(b)",	0xfc000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		0,		I1	},
 {"lwc1",    "T,o(b)",	0x9c000000, 0xfc000000,	RD_b|WR_T|FP_S,		0,		I1	},
@@ -617,7 +620,7 @@ const struct mips_opcode micromips_opcod
 {"lcache",  "t,~(b)",	0x60000000, 0xfc00f000,	RD_b|WR_t,		0,		I1	}, /* same */
 {"lcache",  "t,o(b)",	0,    (int) M_LWL_OB,	INSN_MACRO,		0,		I1	},
 {"lcache",  "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I1	},
-{"lwm",     "mN,mJ(ms)",    0x4500,     0xffc0,	NODS,			MOD_sp,		I1	},
+{"lwm",     "mN,mJ(ms)",    0x4500,     0xffc0,	NODS,			RD_sp,		I1	},
 {"lwm",     "n,~(b)",	0x20005000, 0xfc00f000,	RD_b|NODS,		0,		I1	},
 {"lwm",     "n,o(b)",	0,    (int) M_LWM_OB,	INSN_MACRO,		0,		I1	},
 {"lwm",     "n,A(b)",	0,    (int) M_LWM_AB,	INSN_MACRO,		0,		I1	},
@@ -649,14 +652,14 @@ const struct mips_opcode micromips_opcod
 {"mfhc1",   "t,S",	0x5400303b, 0xfc00ffff,	WR_t|RD_S|FP_D,		0,		I1	},
 {"mfhc1",   "t,G",	0x5400303b, 0xfc00ffff,	WR_t|RD_S|FP_D,		0,		I1	},
 {"mfhc2",   "t,G",	0x00008d3c, 0xfc00ffff,	WR_t|RD_C2,		0,		I1	},
-{"mfhi",    "mj",	    0x4600,     0xffe0,	RD_HI,			MOD_mj,		I1	},
-{"mfhi",    "s",	0x00000d7c, 0xffe0ffff,	RD_HI,			WR_s,		I1	},
-{"mflo",    "mj",	    0x4640,     0xffe0,	RD_LO,			MOD_mj,		I1	},
-{"mflo",    "s",	0x00001d7c, 0xffe0ffff,	RD_LO,			WR_s,		I1	},
+{"mfhi",    "mj",	    0x4600,     0xffe0,	RD_HI,			WR_mj,		I1	},
+{"mfhi",    "s",	0x00000d7c, 0xffe0ffff,	WR_s|RD_HI,		0,		I1	},
+{"mflo",    "mj",	    0x4640,     0xffe0,	RD_LO,			WR_mj,		I1	},
+{"mflo",    "s",	0x00001d7c, 0xffe0ffff,	WR_s|RD_LO,		0,		I1	},
 {"mov.d",   "T,S",	0x5400207b, 0xfc00ffff,	WR_T|RD_S|FP_D,		0,		I1	},
 {"mov.s",   "T,S",	0x5400007b, 0xfc00ffff,	WR_T|RD_S|FP_S,		0,		I1	},
 {"mov.ps",  "T,S",	0x5400407b, 0xfc00ffff,	WR_T|RD_S|FP_D,		0,		I1	},
-{"movep",   "mh,mi,mm,mn",  0x8400,     0xfc01,	NODS,			MOD_mhi|MOD_mm|MOD_mn,	I1	},
+{"movep",   "mh,mi,mm,mn",  0x8400,     0xfc01,	NODS,			WR_mhi|RD_mmn,	I1	},
 {"movf",    "t,s,M",	0x5400017b, 0xfc001fff,	WR_t|RD_s|RD_CC|FP_S|FP_D, 0,		I1	},
 {"movf.d",  "T,S,M",	0x54000220, 0xfc001fff,	WR_T|RD_S|RD_CC|FP_D,	0,		I1	},
 {"movf.s",  "T,S,M",	0x54000020, 0xfc001fff,	WR_T|RD_S|RD_CC|FP_S,	0,		I1	},
@@ -712,19 +715,19 @@ const struct mips_opcode micromips_opcod
 {"nmsub.s", "D,R,S,T",	0x54000022, 0xfc00003f,	RD_R|RD_S|RD_T|WR_D|FP_S, 0,		I1	},
 {"nmsub.ps", "D,R,S,T",	0x54000032, 0xfc00003f,	RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I1	},
 /* nop is at the start of the table.  */
-{"not",     "mf,mg",	    0x4400,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	}, /* put not before nor */
+{"not",     "mf,mg",	    0x4400,     0xffc0,	0,			WR_mf|RD_mg,	I1	}, /* put not before nor */
 {"not",     "d,v",	0x000002d0, 0xffe007ff,	WR_d|RD_s|RD_t,		0,		I1	}, /* nor d,s,0 */
-{"nor",     "mf,mz,mg",	    0x4400,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	}, /* not */
-{"nor",     "mf,mg,mz",	    0x4400,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	}, /* not */
+{"nor",     "mf,mz,mg",	    0x4400,     0xffc0,	0,			WR_mf|RD_mg,	I1	}, /* not */
+{"nor",     "mf,mg,mz",	    0x4400,     0xffc0,	0,			WR_mf|RD_mg,	I1	}, /* not */
 {"nor",     "d,v,t",	0x000002d0, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"nor",     "t,r,I",	0,    (int) M_NOR_I,	INSN_MACRO,		0,		I1	},
-{"or",      "mp,mj,mz",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
-{"or",      "mp,mz,mj",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
-{"or",      "mf,mt,mg",	    0x44c0,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
-{"or",      "mf,mg,mx",	    0x44c0,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
+{"or",      "mp,mj,mz",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
+{"or",      "mp,mz,mj",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
+{"or",      "mf,mt,mg",	    0x44c0,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
+{"or",      "mf,mg,mx",	    0x44c0,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
 {"or",      "d,v,t",	0x00000290, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"or",      "t,r,I",	0,    (int) M_OR_I,	INSN_MACRO,		0,		I1	},
-{"ori",     "mp,mj,mZ",	    0x0c00,     0xfc00,	0,			MOD_mp|MOD_mj,	I1	}, /* move */
+{"ori",     "mp,mj,mZ",	    0x0c00,     0xfc00,	0,			WR_mp|RD_mj,	I1	}, /* move */
 {"ori",     "t,r,i",	0x50000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
 {"pll.ps",  "D,V,T",	0x54000080, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
 {"plu.ps",  "D,V,T",	0x540000c0, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
@@ -758,7 +761,7 @@ const struct mips_opcode micromips_opcod
 {"round.w.s", "T,S",	0x54003b3b, 0xfc00ffff,	WR_T|RD_S|FP_S,		0,		I1	},
 {"rsqrt.d", "T,S",	0x5400423b, 0xfc00ffff,	WR_T|RD_S|FP_D,		0,		I1	},
 {"rsqrt.s", "T,S",	0x5400023b, 0xfc00ffff,	WR_T|RD_S|FP_S,		0,		I1	},
-{"sb",      "mq,mL(ml)",    0x8800,     0xfc00,	SM,			MOD_mq|MOD_ml,		I1	},
+{"sb",      "mq,mL(ml)",    0x8800,     0xfc00,	SM,			RD_mq|RD_ml,		I1	},
 {"sb",      "t,o(b)",	0x18000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"sb",      "t,A(b)",	0,    (int) M_SB_AB,	INSN_MACRO,		0,		I1	},
 {"sc",      "t,~(b)",	0x6000b000, 0xfc00f000,	SM|RD_t|WR_t|RD_b,	0,		I1	},
@@ -809,7 +812,7 @@ const struct mips_opcode micromips_opcod
 {"sgt",     "d,v,I",	0,    (int) M_SGT_I,	INSN_MACRO,		0,		I1	},
 {"sgtu",    "d,v,t",	0,    (int) M_SGTU,	INSN_MACRO,		0,		I1	},
 {"sgtu",    "d,v,I",	0,    (int) M_SGTU_I,	INSN_MACRO,		0,		I1	},
-{"sh",      "mq,mH(ml)",    0xa800,     0xfc00,	SM,			MOD_mq|MOD_ml,	I1	},
+{"sh",      "mq,mH(ml)",    0xa800,     0xfc00,	SM,			RD_mq|RD_ml,	I1	},
 {"sh",      "t,o(b)",	0x38000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"sh",      "t,A(b)",	0,    (int) M_SH_AB,	INSN_MACRO,		0,		I1	},
 {"sle",     "d,v,t",	0,    (int) M_SLE,	INSN_MACRO,		0,		I1	},
@@ -817,7 +820,7 @@ const struct mips_opcode micromips_opcod
 {"sleu",    "d,v,t",	0,    (int) M_SLEU,	INSN_MACRO,		0,		I1	},
 {"sleu",    "d,v,I",	0,    (int) M_SLEU_I,	INSN_MACRO,		0,		I1	},
 {"sllv",    "d,t,s",	0x00000010, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
-{"sll",     "md,mc,mM",	    0x2400,     0xfc01,	0,			MOD_md|MOD_mc,	I1	},
+{"sll",     "md,mc,mM",	    0x2400,     0xfc01,	0,			WR_md|RD_mc,	I1	},
 {"sll",     "d,w,s",	0x00000010, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	}, /* sllv */
 {"sll",     "t,r,<",	0x00000000, 0xfc0007ff,	WR_t|RD_s,		0,		I1	},
 {"slt",     "d,v,t",	0x00000350, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
@@ -834,7 +837,7 @@ const struct mips_opcode micromips_opcod
 {"sra",     "d,w,s",	0x00000090, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	}, /* srav */
 {"sra",     "t,r,<",	0x00000080, 0xfc0007ff,	WR_t|RD_s,		0,		I1	},
 {"srlv",    "d,t,s",	0x00000050, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	},
-{"srl",     "md,mc,mM",	    0x2401,     0xfc01,	0,			MOD_md|MOD_mc,	I1	},
+{"srl",     "md,mc,mM",	    0x2401,     0xfc01,	0,			WR_md|RD_mc,	I1	},
 {"srl",     "d,w,s",	0x00000050, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	}, /* srlv */
 {"srl",     "t,r,<",	0x00000040, 0xfc0007ff,	WR_t|RD_s,		0,		I1	},
 /* ssnop is at the start of the table.  */
@@ -843,12 +846,12 @@ const struct mips_opcode micromips_opcod
 {"sub.d",   "D,V,T",	0x54000170, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
 {"sub.s",   "D,V,T",	0x54000070, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
 {"sub.ps",  "D,V,T",	0x54000270, 0xfc0007ff,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
-{"subu",    "md,me,ml",	    0x0401,     0xfc01,	0,			MOD_md|MOD_me|MOD_ml,	I1	},
+{"subu",    "md,me,ml",	    0x0401,     0xfc01,	0,			WR_md|RD_me|RD_ml,	I1	},
 {"subu",    "d,v,t",	0x000001d0, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"subu",    "d,v,I",	0,    (int) M_SUBU_I,	INSN_MACRO,		0,		I1	},
 {"suxc1",   "D,t(b)",	0x54000188, 0xfc0007ff,	SM|RD_t|RD_b|FP_D,	RD_D,		I1	},
-{"sw",      "mq,mJ(ml)",    0xe800,     0xfc00,	SM,			MOD_mq|MOD_ml,	I1	},
-{"sw",      "mp,mU(ms)",    0xc800,     0xfc00,	SM,			MOD_mp|MOD_sp,	I1	}, /* swsp */
+{"sw",      "mq,mJ(ml)",    0xe800,     0xfc00,	SM,			RD_mq|RD_ml,	I1	},
+{"sw",      "mp,mU(ms)",    0xc800,     0xfc00,	SM,			RD_mp|RD_sp,	I1	}, /* swsp */
 {"sw",      "t,o(b)",	0xf8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
 {"sw",      "t,A(b)",	0,    (int) M_SW_AB,	INSN_MACRO,		0,		I1	},
 {"swc1",    "T,o(b)",	0x98000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
@@ -866,7 +869,7 @@ const struct mips_opcode micromips_opcod
 {"scache",  "t,~(b)",	0x60008000, 0xfc00f000,	SM|RD_t|RD_b,		0,		I1	}, /* same */
 {"scache",  "t,o(b)",	0,    (int) M_SWL_OB,	INSN_MACRO,		0,		I1	},
 {"scache",  "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I1	},
-{"swm",     "mN,mJ(ms)",    0x4540,     0xffc0,	NODS,			MOD_sp,		I1	},
+{"swm",     "mN,mJ(ms)",    0x4540,     0xffc0,	NODS,			RD_sp,		I1	},
 {"swm",     "n,~(b)",	0x2000d000, 0xfc00f000,	SM|RD_b|NODS,		0,		I1	},
 {"swm",     "n,o(b)",	0,    (int) M_SWM_OB,	INSN_MACRO,		0,		I1	},
 {"swm",     "n,A(b)",	0,    (int) M_SWM_AB,	INSN_MACRO,		0,		I1	},
@@ -946,8 +949,8 @@ const struct mips_opcode micromips_opcod
 {"wait",    "B",	0x0000937c, 0xfc00ffff,	NODS,			0,		I1	},
 {"wrpgpr",  "t,r",	0x0000f17c, 0xfc00ffff,	RD_s,			0,		I1	},
 {"wsbh",    "t,r",	0x00007b3c, 0xfc00ffff,	WR_t|RD_s,		0,		I1	},
-{"xor",     "mf,mt,mg",	    0x4440,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
-{"xor",     "mf,mg,mx",	    0x4440,     0xffc0,	0,			MOD_mf|MOD_mg,	I1	},
+{"xor",     "mf,mt,mg",	    0x4440,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
+{"xor",     "mf,mg,mx",	    0x4440,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
 {"xor",     "d,v,t",	0x00000310, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
 {"xor",     "t,r,I",	0,    (int) M_XOR_I,	INSN_MACRO,		0,		I1	},
 {"xori",    "t,r,i",	0x70000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2011-08-02 16:38:23.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2011-08-02 18:07:59.000000000 +0100
@@ -2897,33 +2897,8 @@ gpr_mod_mask (const struct mips_cl_insn 
   pinfo2 = ip->insn_mo->pinfo2;
   if (mips_opts.micromips)
     {
-      if (pinfo2 & INSN2_MOD_GPR_MB)
-	mask |= 1 << micromips_to_32_reg_b_map[EXTRACT_OPERAND (1, MB, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MC)
-	mask |= 1 << micromips_to_32_reg_c_map[EXTRACT_OPERAND (1, MC, *ip)];
       if (pinfo2 & INSN2_MOD_GPR_MD)
 	mask |= 1 << micromips_to_32_reg_d_map[EXTRACT_OPERAND (1, MD, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_ME)
-	mask |= 1 << micromips_to_32_reg_e_map[EXTRACT_OPERAND (1, ME, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MF)
-	mask |= 1 << micromips_to_32_reg_f_map[EXTRACT_OPERAND (1, MF, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MG)
-	mask |= 1 << micromips_to_32_reg_g_map[EXTRACT_OPERAND (1, MG, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MHI)
-	{
-	  mask |= 1 << micromips_to_32_reg_h_map[EXTRACT_OPERAND (1, MH, *ip)];
-	  mask |= 1 << micromips_to_32_reg_i_map[EXTRACT_OPERAND (1, MI, *ip)];
-	}
-      if (pinfo2 & INSN2_MOD_GPR_MJ)
-	mask |= 1 << EXTRACT_OPERAND (1, MJ, *ip);
-      if (pinfo2 & INSN2_MOD_GPR_MM)
-	mask |= 1 << micromips_to_32_reg_m_map[EXTRACT_OPERAND (1, MM, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MN)
-	mask |= 1 << micromips_to_32_reg_n_map[EXTRACT_OPERAND (1, MN, *ip)];
-      if (pinfo2 & INSN2_MOD_GPR_MP)
-	mask |= 1 << EXTRACT_OPERAND (1, MP, *ip);
-      if (pinfo2 & INSN2_MOD_GPR_MQ)
-	mask |= 1 << micromips_to_32_reg_q_map[EXTRACT_OPERAND (1, MQ, *ip)];
       if (pinfo2 & INSN2_MOD_SP)
 	mask |= 1 << SP;
     }
@@ -2974,6 +2949,26 @@ gpr_read_mask (const struct mips_cl_insn
       if (pinfo2 & INSN2_READ_GPR_Z)
 	mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
     }
+  if (mips_opts.micromips)
+    {
+      if (pinfo2 & INSN2_READ_GPR_MC)
+	mask |= 1 << micromips_to_32_reg_c_map[EXTRACT_OPERAND (1, MC, *ip)];
+      if (pinfo2 & INSN2_READ_GPR_ME)
+	mask |= 1 << micromips_to_32_reg_e_map[EXTRACT_OPERAND (1, ME, *ip)];
+      if (pinfo2 & INSN2_READ_GPR_MG)
+	mask |= 1 << micromips_to_32_reg_g_map[EXTRACT_OPERAND (1, MG, *ip)];
+      if (pinfo2 & INSN2_READ_GPR_MJ)
+	mask |= 1 << EXTRACT_OPERAND (1, MJ, *ip);
+      if (pinfo2 & INSN2_READ_GPR_MMN)
+	{
+	  mask |= 1 << micromips_to_32_reg_m_map[EXTRACT_OPERAND (1, MM, *ip)];
+	  mask |= 1 << micromips_to_32_reg_n_map[EXTRACT_OPERAND (1, MN, *ip)];
+	}
+      if (pinfo2 & INSN2_READ_GPR_MP)
+	mask |= 1 << EXTRACT_OPERAND (1, MP, *ip);
+      if (pinfo2 & INSN2_READ_GPR_MQ)
+	mask |= 1 << micromips_to_32_reg_q_map[EXTRACT_OPERAND (1, MQ, *ip)];
+    }
   /* Don't include register 0.  */
   return mask & ~1;
 }
@@ -3012,13 +3007,29 @@ gpr_write_mask (const struct mips_cl_ins
 	mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
       if (pinfo & INSN_WRITE_GPR_T)
 	mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
-      if (pinfo2 & INSN2_WRITE_GPR_S)
+      if (pinfo & INSN_WRITE_GPR_S)
 	mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
       if (pinfo & INSN_WRITE_GPR_31)
 	mask |= 1 << RA;
       if (pinfo2 & INSN2_WRITE_GPR_Z)
 	mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
     }
+  if (mips_opts.micromips)
+    {
+      if (pinfo2 & INSN2_WRITE_GPR_MB)
+	mask |= 1 << micromips_to_32_reg_b_map[EXTRACT_OPERAND (1, MB, *ip)];
+      if (pinfo2 & INSN2_WRITE_GPR_MF)
+	mask |= 1 << micromips_to_32_reg_f_map[EXTRACT_OPERAND (1, MF, *ip)];
+      if (pinfo2 & INSN2_WRITE_GPR_MHI)
+	{
+	  mask |= 1 << micromips_to_32_reg_h_map[EXTRACT_OPERAND (1, MH, *ip)];
+	  mask |= 1 << micromips_to_32_reg_i_map[EXTRACT_OPERAND (1, MI, *ip)];
+	}
+      if (pinfo2 & INSN2_WRITE_GPR_MJ)
+	mask |= 1 << EXTRACT_OPERAND (1, MJ, *ip);
+      if (pinfo2 & INSN2_WRITE_GPR_MP)
+	mask |= 1 << EXTRACT_OPERAND (1, MP, *ip);
+    }
   /* Don't include register 0.  */
   return mask & ~1;
 }
@@ -3636,12 +3647,9 @@ fix_loongson2f (struct mips_cl_insn * ip
 static bfd_boolean
 can_swap_branch_p (struct mips_cl_insn *ip)
 {
-  unsigned long pinfo, pinfo2, prev_pinfo;
+  unsigned long pinfo, pinfo2, prev_pinfo, prev_pinfo2;
   unsigned int gpr_read, gpr_write, prev_gpr_read, prev_gpr_write;
 
-  /* For microMIPS, disable reordering.  */
-  if (mips_opts.micromips)
-    return FALSE;
 
   /* -O2 and above is required for this optimization.  */
   if (mips_optimize < 2)
@@ -3741,8 +3749,11 @@ can_swap_branch_p (struct mips_cl_insn *
     return FALSE;
 
   /* If the previous instruction uses the PC, we can not swap.  */
+  prev_pinfo2 = history[0].insn_mo->pinfo2;
   if (mips_opts.mips16 && (prev_pinfo & MIPS16_INSN_READ_PC))
     return FALSE;
+  if (mips_opts.micromips && (prev_pinfo2 & INSN2_READ_PC))
+    return FALSE;
 
   /* If the previous instruction has an incorrect size for a fixed
      branch delay slot in microMIPS mode, we cannot swap.  */
@@ -3950,6 +3961,7 @@ append_insn (struct mips_cl_insn *ip, ex
   bfd_boolean relaxed_branch = FALSE;
   enum append_method method;
   bfd_boolean relax32;
+  int branch_disp;
 
   if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
     fix_loongson2f (ip);
@@ -4142,6 +4154,7 @@ append_insn (struct mips_cl_insn *ip, ex
     }
 
   method = get_append_method (ip);
+  branch_disp = method == APPEND_SWAP ? insn_length (history) : 0;
 
 #ifdef OBJ_ELF
   /* The value passed to dwarf2_emit_insn is the distance between
@@ -4159,8 +4172,7 @@ append_insn (struct mips_cl_insn *ip, ex
      and for MIPS16/microMIPS code also prevents a debugger from
      placing a breakpoint in the middle of the branch (and corrupting
      code if software breakpoints are used).  */
-  dwarf2_emit_insn ((HAVE_CODE_COMPRESSION ? -1 : 0)
-		    + (method == APPEND_SWAP ? insn_length (history) : 0));
+  dwarf2_emit_insn ((HAVE_CODE_COMPRESSION ? -1 : 0) + branch_disp);
 #endif
 
   relax32 = (mips_relax_branch
@@ -4219,6 +4231,7 @@ append_insn (struct mips_cl_insn *ip, ex
       gas_assert (address_expr != NULL);
       gas_assert (!mips_relax.sequence);
 
+      relaxed_branch = TRUE;
       length32 = relaxed_micromips_32bit_branch_length (NULL, NULL, uncond);
       add_relaxed_insn (ip, relax32 ? length32 : 4, relax16 ? 2 : 4,
 			RELAX_MICROMIPS_ENCODE (type, AT, uncond, compact, al,
@@ -4438,25 +4451,21 @@ append_insn (struct mips_cl_insn *ip, ex
 	    move_insn (ip, delay.frag, delay.where);
 	    move_insn (&delay, ip->frag, ip->where + insn_length (ip));
 	  }
-	else if (mips_opts.micromips)
-	  {
-	    /* We don't reorder for micromips.  */
-	    abort ();
-	  }
 	else if (relaxed_branch)
 	  {
 	    /* Add the delay slot instruction to the end of the
 	       current frag and shrink the fixed part of the
 	       original frag.  If the branch occupies the tail of
 	       the latter, move it backwards to cover the gap.  */
-	    delay.frag->fr_fix -= 4;
+	    delay.frag->fr_fix -= branch_disp;
 	    if (delay.frag == ip->frag)
-	      move_insn (ip, ip->frag, ip->where - 4);
+	      move_insn (ip, ip->frag, ip->where - branch_disp);
 	    add_fixed_insn (&delay);
 	  }
 	else
 	  {
-	    move_insn (&delay, ip->frag, ip->where);
+	    move_insn (&delay, ip->frag,
+		       ip->where - branch_disp + insn_length (ip));
 	    move_insn (ip, history[0].frag, history[0].where);
 	  }
 	history[0] = *ip;
Index: binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips-trap.d
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/testsuite/gas/mips/micromips-trap.d	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips-trap.d	2011-08-02 18:07:59.000000000 +0100
@@ -108,10 +108,9 @@
 [ 0-9a-f]+:	0c56      	move	v0,s6
 [ 0-9a-f]+:	0ec2      	move	s6,v0
 [ 0-9a-f]+:	0016 1150 	move	v0,s6
-[ 0-9a-f]+:	0002 b150 	move	s6,v0
 [ 0-9a-f]+:	cfff      	b	[0-9a-f]+ <test\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	test
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0002 b150 	move	s6,v0
 [ 0-9a-f]+:	cfff      	b	[0-9a-f]+ <test\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	test
 [ 0-9a-f]+:	0c00      	nop
@@ -346,10 +345,9 @@
 [ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	41a1 ffff 	lui	at,0xffff
 [ 0-9a-f]+:	5021 0001 	ori	at,at,0x1
-[ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	4280 fffe 	bc2f	[0-9a-f]+ <.*\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	test
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	4280 fffe 	bc2f	[0-9a-f]+ <.*\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	test
 [ 0-9a-f]+:	0c00      	nop
@@ -954,9 +952,8 @@
 [ 0-9a-f]+:	0043 994c 	ins	v0,v1,0x5,0xf
 [ 0-9a-f]+:	0043 f80c 	ins	v0,v1,0x0,0x20
 [ 0-9a-f]+:	0043 ffcc 	ins	v0,v1,0x1f,0x1
-[ 0-9a-f]+:	03fe ffcc 	ins	ra,s8,0x1f,0x1
 [ 0-9a-f]+:	4580      	jr	zero
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	03fe ffcc 	ins	ra,s8,0x1f,0x1
 [ 0-9a-f]+:	4582      	jr	v0
 [ 0-9a-f]+:	0c00      	nop
 [ 0-9a-f]+:	4583      	jr	v1
@@ -5182,6 +5179,8 @@
 [ 0-9a-f]+:	03ff 937c 	wait	0x3ff
 [ 0-9a-f]+:	03ff 8b7c 	syscall	0x3ff
 [ 0-9a-f]+:	03ff fffa 	cop2	0x7fffff
+[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0000 0000 	nop
 
 [0-9a-f]+ <fp_test>:
 [ 0-9a-f]+:	5400 01a0 	prefx	0x0,zero\(zero\)
Index: binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips.d
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/testsuite/gas/mips/micromips.d	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips.d	2011-08-02 18:07:59.000000000 +0100
@@ -108,10 +108,9 @@
 [ 0-9a-f]+:	0c56      	move	v0,s6
 [ 0-9a-f]+:	0ec2      	move	s6,v0
 [ 0-9a-f]+:	0016 1150 	move	v0,s6
-[ 0-9a-f]+:	0002 b150 	move	s6,v0
 [ 0-9a-f]+:	cfff      	b	[0-9a-f]+ <test\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	test
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0002 b150 	move	s6,v0
 [ 0-9a-f]+:	cfff      	b	[0-9a-f]+ <test\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	test
 [ 0-9a-f]+:	0c00      	nop
@@ -346,10 +345,9 @@
 [ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	41a1 ffff 	lui	at,0xffff
 [ 0-9a-f]+:	5021 0001 	ori	at,at,0x1
-[ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	4280 fffe 	bc2f	[0-9a-f]+ <.*\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	test
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0023 1250 	and	v0,v1,at
 [ 0-9a-f]+:	4280 fffe 	bc2f	[0-9a-f]+ <.*\+0x[0-9a-f]+>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	test
 [ 0-9a-f]+:	0c00      	nop
@@ -969,9 +967,8 @@
 [ 0-9a-f]+:	0043 994c 	ins	v0,v1,0x5,0xf
 [ 0-9a-f]+:	0043 f80c 	ins	v0,v1,0x0,0x20
 [ 0-9a-f]+:	0043 ffcc 	ins	v0,v1,0x1f,0x1
-[ 0-9a-f]+:	03fe ffcc 	ins	ra,s8,0x1f,0x1
 [ 0-9a-f]+:	4580      	jr	zero
-[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	03fe ffcc 	ins	ra,s8,0x1f,0x1
 [ 0-9a-f]+:	4582      	jr	v0
 [ 0-9a-f]+:	0c00      	nop
 [ 0-9a-f]+:	4583      	jr	v1
@@ -5254,6 +5251,8 @@
 [ 0-9a-f]+:	03ff 937c 	wait	0x3ff
 [ 0-9a-f]+:	03ff 8b7c 	syscall	0x3ff
 [ 0-9a-f]+:	03ff fffa 	cop2	0x7fffff
+[ 0-9a-f]+:	0c00      	nop
+[ 0-9a-f]+:	0000 0000 	nop
 
 [0-9a-f]+ <fp_test>:
 [ 0-9a-f]+:	5400 01a0 	prefx	0x0,zero\(zero\)
Index: binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@jal-svr4pic.d
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/testsuite/gas/mips/micromips@jal-svr4pic.d	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@jal-svr4pic.d	2011-08-02 18:07:59.000000000 +0100
@@ -39,9 +39,7 @@
 [0-9a-f]+ <[^>]*> 03f9 4f3c 	jalrs	t9
 [ 	]*[0-9a-f]+: R_MICROMIPS_JALR	external_text_label
 [0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> ff9d 0000 	lw	gp,0\(sp\)
 ([0-9a-f]+) <[^>]*> 9400 fffe 	b	\1 <.*>
 [ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	text_label
-[0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0c00      	nop
+[0-9a-f]+ <[^>]*> ff9d 0000 	lw	gp,0\(sp\)
 	\.\.\.
Index: binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@loc-swap-dis.d
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/testsuite/gas/mips/micromips@loc-swap-dis.d	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@loc-swap-dis.d	2011-08-02 18:07:59.000000000 +0100
@@ -11,12 +11,10 @@
 [0-9a-f]+ <[^>]*> 0c90      	move	a0,s0
 [0-9a-f]+ <[^>]*> 4584      	jr	a0
 [0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0ff0      	move	ra,s0
 [0-9a-f]+ <[^>]*> 4584      	jr	a0
-[0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0c90      	move	a0,s0
+[0-9a-f]+ <[^>]*> 0ff0      	move	ra,s0
 [0-9a-f]+ <[^>]*> 459f      	jr	ra
-[0-9a-f]+ <[^>]*> 0c00      	nop
+[0-9a-f]+ <[^>]*> 0c90      	move	a0,s0
 [0-9a-f]+ <[^>]*> 0ff0      	move	ra,s0
 [0-9a-f]+ <[^>]*> 459f      	jr	ra
 [0-9a-f]+ <[^>]*> 0c00      	nop
Index: binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@loc-swap.d
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/testsuite/gas/mips/micromips@loc-swap.d	2011-07-29 22:53:43.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/testsuite/gas/mips/micromips@loc-swap.d	2011-08-02 18:07:59.000000000 +0100
@@ -45,18 +45,18 @@
   Special opcode 11: advance Address by 0 to 0x1 and Line by 6 to 7
   Special opcode 35: advance Address by 2 to 0x3 and Line by 2 to 9
   Special opcode 64: advance Address by 4 to 0x7 and Line by 3 to 12
-  Special opcode 35: advance Address by 2 to 0x9 and Line by 2 to 14
-  Special opcode 64: advance Address by 4 to 0xd and Line by 3 to 17
-  Special opcode 35: advance Address by 2 to 0xf and Line by 2 to 19
-  Special opcode 64: advance Address by 4 to 0x13 and Line by 3 to 22
-  Special opcode 35: advance Address by 2 to 0x15 and Line by 2 to 24
-  Special opcode 64: advance Address by 4 to 0x19 and Line by 3 to 27
-  Special opcode 35: advance Address by 2 to 0x1b and Line by 2 to 29
-  Special opcode 92: advance Address by 6 to 0x21 and Line by 3 to 32
-  Special opcode 35: advance Address by 2 to 0x23 and Line by 2 to 34
-  Special opcode 92: advance Address by 6 to 0x29 and Line by 3 to 37
-  Special opcode 35: advance Address by 2 to 0x2b and Line by 2 to 39
-  Special opcode 120: advance Address by 8 to 0x33 and Line by 3 to 42
-  Special opcode 35: advance Address by 2 to 0x35 and Line by 2 to 44
-  Advance PC by 23 to 0x4c
+  Special opcode 7: advance Address by 0 to 0x7 and Line by 2 to 14
+  Special opcode 64: advance Address by 4 to 0xb and Line by 3 to 17
+  Special opcode 7: advance Address by 0 to 0xb and Line by 2 to 19
+  Special opcode 64: advance Address by 4 to 0xf and Line by 3 to 22
+  Special opcode 35: advance Address by 2 to 0x11 and Line by 2 to 24
+  Special opcode 64: advance Address by 4 to 0x15 and Line by 3 to 27
+  Special opcode 35: advance Address by 2 to 0x17 and Line by 2 to 29
+  Special opcode 92: advance Address by 6 to 0x1d and Line by 3 to 32
+  Special opcode 35: advance Address by 2 to 0x1f and Line by 2 to 34
+  Special opcode 92: advance Address by 6 to 0x25 and Line by 3 to 37
+  Special opcode 35: advance Address by 2 to 0x27 and Line by 2 to 39
+  Special opcode 120: advance Address by 8 to 0x2f and Line by 3 to 42
+  Special opcode 35: advance Address by 2 to 0x31 and Line by 2 to 44
+  Advance PC by 23 to 0x48
   Extended opcode 1: End of Sequence
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2011-08-02 14:44:25.000000000 +0100
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2011-08-02 18:07:59.000000000 +0100
@@ -585,6 +585,8 @@ struct mips_opcode
 #define FP_D			    0x20000000
 /* Instruction is part of the tx39's integer multiply family.    */
 #define INSN_MULT                   0x40000000
+/* Modifies the general purpose register in MICROMIPSOP_*_RS.  */
+#define INSN_WRITE_GPR_S	    0x80000000
 /* Instruction is actually a macro.  It should be ignored by the
    disassembler, and requires special treatment by the assembler.  */
 #define INSN_MACRO                  0xffffffff
@@ -622,46 +624,46 @@ struct mips_opcode
 #define INSN2_BRANCH_DELAY_16BIT    0x00000400
 /* Instruction has a branch delay slot that requires a 32-bit instruction.  */
 #define INSN2_BRANCH_DELAY_32BIT    0x00000800
-/* Modifies the general purpose register in MICROMIPSOP_*_RS.  */
-#define INSN2_WRITE_GPR_S	    0x00001000
 /* Reads the floating point register in MICROMIPSOP_*_FD.  */
-#define INSN2_READ_FPR_D	    0x00002000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MB.  */
-#define INSN2_MOD_GPR_MB	    0x00004000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MC.  */
-#define INSN2_MOD_GPR_MC	    0x00008000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MD.  */
-#define INSN2_MOD_GPR_MD	    0x00010000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_ME.  */
-#define INSN2_MOD_GPR_ME	    0x00020000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MF.  */
-#define INSN2_MOD_GPR_MF	    0x00040000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MG.  */
-#define INSN2_MOD_GPR_MG	    0x00080000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MJ.  */
-#define INSN2_MOD_GPR_MJ	    0x00100000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MP.  */
-#define INSN2_MOD_GPR_MP	    0x00200000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MQ.  */
-#define INSN2_MOD_GPR_MQ	    0x00400000
+#define INSN2_READ_FPR_D	    0x00001000
+/* Modifies the general purpose register in MICROMIPSOP_*_MB.  */
+#define INSN2_WRITE_GPR_MB	    0x00002000
+/* Reads the general purpose register in MICROMIPSOP_*_MC.  */
+#define INSN2_READ_GPR_MC	    0x00004000
+/* Reads/writes the general purpose register in MICROMIPSOP_*_MD.  */
+#define INSN2_MOD_GPR_MD	    0x00008000
+/* Reads the general purpose register in MICROMIPSOP_*_ME.  */
+#define INSN2_READ_GPR_ME	    0x00010000
+/* Modifies the general purpose register in MICROMIPSOP_*_MF.  */
+#define INSN2_WRITE_GPR_MF	    0x00020000
+/* Reads the general purpose register in MICROMIPSOP_*_MG.  */
+#define INSN2_READ_GPR_MG	    0x00040000
+/* Reads the general purpose register in MICROMIPSOP_*_MJ.  */
+#define INSN2_READ_GPR_MJ	    0x00080000
+/* Modifies the general purpose register in MICROMIPSOP_*_MJ.  */
+#define INSN2_WRITE_GPR_MJ	    0x00100000
+/* Reads the general purpose register in MICROMIPSOP_*_MP.  */
+#define INSN2_READ_GPR_MP	    0x00200000
+/* Modifies the general purpose register in MICROMIPSOP_*_MP.  */
+#define INSN2_WRITE_GPR_MP	    0x00400000
+/* Reads the general purpose register in MICROMIPSOP_*_MQ.  */
+#define INSN2_READ_GPR_MQ	    0x00800000
 /* Reads/Writes the stack pointer ($29).  */
-#define INSN2_MOD_SP		    0x00800000
+#define INSN2_MOD_SP		    0x01000000
 /* Reads the RA ($31) register.  */
-#define INSN2_READ_GPR_31	    0x01000000
+#define INSN2_READ_GPR_31	    0x02000000
 /* Reads the global pointer ($28).  */
-#define INSN2_READ_GP		    0x02000000
+#define INSN2_READ_GP		    0x04000000
 /* Reads the program counter ($pc).  */
-#define INSN2_READ_PC		    0x04000000
+#define INSN2_READ_PC		    0x08000000
 /* Is an unconditional branch insn. */
-#define INSN2_UNCOND_BRANCH	    0x08000000
+#define INSN2_UNCOND_BRANCH	    0x10000000
 /* Is a conditional branch insn. */
-#define INSN2_COND_BRANCH	    0x10000000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MH/I.  */
-#define INSN2_MOD_GPR_MHI	    0x20000000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MM.  */
-#define INSN2_MOD_GPR_MM	    0x40000000
-/* Reads/Writes the general purpose registers in MICROMIPSOP_*_MN.  */
-#define INSN2_MOD_GPR_MN	    0x80000000
+#define INSN2_COND_BRANCH	    0x20000000
+/* Modifies the general purpose registers in MICROMIPSOP_*_MH/I.  */
+#define INSN2_WRITE_GPR_MHI	    0x40000000
+/* Reads the general purpose registers in MICROMIPSOP_*_MM/N.  */
+#define INSN2_READ_GPR_MMN	    0x80000000
 
 /* Masks used to mark instructions to indicate which MIPS ISA level
    they were introduced in.  INSN_ISA_MASK masks an enumeration that


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]