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]

Re: [PATCH] microMIPS: Branch swapping support


On Sat, 6 Aug 2011, Richard Sandiford wrote:

> >  /* 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	},
> 
> Unless I'm missing something, it looks like this loses the read from mf.
> Same for OR and XOR.

 Indeed, sigh...  Thanks for catching it.

 And as we've run out of pinfo bits, here's an update that brings 
INSN2_MOD_GPR_MF back, except that the opcode table now uses separate 
RD_mf and WR_mf macros, similarly to INSN2_MOD_GPR_MD vs RD_md/WR_md.  
This will make it easier to convert to separate pinfo bits if we ever get 
some more.  The new arrangement penalises the short form of the NOT 
instruction (and some NOR cases that decay to same) that is now treated as 
if it read its destination register.

 OK with this update?

2011-08-08  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): Change the bit used.
	(INSN2_MOD_GPR_MD, INSN2_MOD_GPR_MF): Likewise.
	(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_MG): Likewise.
	(INSN2_MOD_GPR_MJ, INSN2_MOD_GPR_MP, INSN2_MOD_GPR_MQ): Likewise.
	(INSN2_MOD_GPR_MHI, INSN2_MOD_GPR_MM): Likewise.
	(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_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_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, RD_mf, WR_mf): New macros.
	(RD_mg, WR_mhi, RD_mj, WR_mj, RD_ml, RD_mmn): Likewise.
	(RD_mp, WR_mp, 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-fix.diff
Index: binutils-fsf-trunk-quilt/opcodes/micromips-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/micromips-opc.c	2011-08-08 01:30:32.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/micromips-opc.c	2011-08-08 01:16:44.000000000 +0100
@@ -39,7 +39,8 @@
 #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_mf	INSN2_MOD_GPR_MF
+#define WR_mf	INSN2_MOD_GPR_MF
 #define RD_mg	INSN2_READ_GPR_MG
 #define WR_mhi	INSN2_WRITE_GPR_MHI
 #define RD_mj	INSN2_READ_GPR_MJ
@@ -163,8 +164,8 @@ const struct mips_opcode micromips_opcod
 /* 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,			WR_mf|RD_mg,	I1	},
-{"and",     "mf,mg,mx",	    0x4480,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
+{"and",     "mf,mt,mg",	    0x4480,     0xffc0,	0,			WR_mf|RD_mf|RD_mg,	I1	},
+{"and",     "mf,mg,mx",	    0x4480,     0xffc0,	0,			WR_mf|RD_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,			WR_md|RD_mc,	I1	},
@@ -723,8 +724,8 @@ const struct mips_opcode micromips_opcod
 {"nor",     "t,r,I",	0,    (int) M_NOR_I,	INSN_MACRO,		0,		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",      "mf,mt,mg",	    0x44c0,     0xffc0,	0,			WR_mf|RD_mf|RD_mg,	I1	},
+{"or",      "mf,mg,mx",	    0x44c0,     0xffc0,	0,			WR_mf|RD_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,			WR_mp|RD_mj,	I1	}, /* move */
@@ -949,8 +950,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,			WR_mf|RD_mg,	I1	},
-{"xor",     "mf,mg,mx",	    0x4440,     0xffc0,	0,			WR_mf|RD_mg,	I1	},
+{"xor",     "mf,mt,mg",	    0x4440,     0xffc0,	0,			WR_mf|RD_mf|RD_mg,	I1	},
+{"xor",     "mf,mg,mx",	    0x4440,     0xffc0,	0,			WR_mf|RD_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-08 01:30:32.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2011-08-08 01:17:55.000000000 +0100
@@ -2899,6 +2899,8 @@ gpr_mod_mask (const struct mips_cl_insn 
     {
       if (pinfo2 & INSN2_MOD_GPR_MD)
 	mask |= 1 << micromips_to_32_reg_d_map[EXTRACT_OPERAND (1, MD, *ip)];
+      if (pinfo2 & INSN2_MOD_GPR_MF)
+	mask |= 1 << micromips_to_32_reg_f_map[EXTRACT_OPERAND (1, MF, *ip)];
       if (pinfo2 & INSN2_MOD_SP)
 	mask |= 1 << SP;
     }
@@ -3018,8 +3020,6 @@ gpr_write_mask (const struct mips_cl_ins
     {
       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)];
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2011-08-08 01:30:32.000000000 +0100
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2011-08-08 01:18:37.000000000 +0100
@@ -634,8 +634,8 @@ struct mips_opcode
 #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/writes the general purpose register in MICROMIPSOP_*_MF.  */
+#define INSN2_MOD_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.  */


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