[MIPS] Extending -mfix-vr4120 to cope with VR4181A errata

Richard Sandiford rsandifo@redhat.com
Fri May 7 13:31:00 GMT 2004


The VR4120 core is used in the VR4121, VR4122 and VR4181A.  At the moment,
-mfix-vr4120 works around errata in the VR412x versions.  This patch extends
it to cope with the VR4181A multiplication/division errata.

There are four such errata, MD(1)...MD(4).  However, MD(2) and MD(3) are
the same as for the VR412x, so new code is only needed for MD(1) and MD(4).
I've quoted them in the comments.

Patch tested against the binutils testsuite on mips-elf.  Also tested
on a combined gcc/binutils tree for mips64vrel-elf (which builds
-mfix-vr4120 multilibs).  OK to install?

Richard

(I guess it's a bit odd adding VR4181A stuff to files called vr4122.[sd],
but I'd prefer to keep the tests for this option in a single file if
possible.  Will rename it to fix-vr4120.[sd] or something if you'd prefer.)


gas/
	* config/tc-mips.c (append_insn, mips_emit_delays): Extend -mfix-vr4120
	to cope with VR4181A errata MD(1) and MD(4).

gas/testsuite/
	* gas/mips/vr4122.[sd]: Add tests for VR4181A errata MD(1) and MD(4).


Index: config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.263
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.263 tc-mips.c
*** config/tc-mips.c	29 Apr 2004 05:14:21 -0000	1.263
--- config/tc-mips.c	7 May 2004 13:15:00 -0000
*************** #define emit_nop()					\
*** 1858,1895 ****
  	  int min_nops = 0;
  	  const char *pn = prev_insn.insn_mo->name;
  	  const char *tn = ip->insn_mo->name;
! 	  if (strncmp(pn, "macc", 4) == 0
! 	      || strncmp(pn, "dmacc", 5) == 0)
  	    {
  	      /* Errata 21 - [D]DIV[U] after [D]MACC */
  	      if (strstr (tn, "div"))
! 		{
! 		  min_nops = 1;
! 		}
  
! 	      /* Errata 23 - Continuous DMULT[U]/DMACC instructions */
! 	      if (pn[0] == 'd' /* dmacc */
! 		  && (strncmp(tn, "dmult", 5) == 0
! 		      || strncmp(tn, "dmacc", 5) == 0))
! 		{
! 		  min_nops = 1;
! 		}
  
  	      /* Errata 24 - MT{LO,HI} after [D]MACC */
  	      if (strcmp (tn, "mtlo") == 0
  		  || strcmp (tn, "mthi") == 0)
! 		{
! 		  min_nops = 1;
! 		}
! 
  	    }
! 	  else if (strncmp(pn, "dmult", 5) == 0
! 		   && (strncmp(tn, "dmult", 5) == 0
! 		       || strncmp(tn, "dmacc", 5) == 0))
  	    {
  	      /* Here is the rest of errata 23.  */
  	      min_nops = 1;
  	    }
  	  if (nops < min_nops)
  	    nops = min_nops;
  	}
--- 1858,1906 ----
  	  int min_nops = 0;
  	  const char *pn = prev_insn.insn_mo->name;
  	  const char *tn = ip->insn_mo->name;
! 	  if (strncmp (pn, "macc", 4) == 0
! 	      || strncmp (pn, "dmacc", 5) == 0)
  	    {
  	      /* Errata 21 - [D]DIV[U] after [D]MACC */
  	      if (strstr (tn, "div"))
! 		min_nops = 1;
  
! 	      /* VR4181A errata MD(1): "If a MULT, MULTU, DMULT or DMULTU
! 		 instruction is executed immediately after a MACC or
! 		 DMACC instruction, the result of [either instruction]
! 		 is incorrect."  */
! 	      if (strncmp (tn, "mult", 4) == 0
! 		  || strncmp (tn, "dmult", 5) == 0)
! 		min_nops = 1;
! 
! 	      /* Errata 23 - Continuous DMULT[U]/DMACC instructions.
! 		 Applies on top of VR4181A MD(1) errata.  */
! 	      if (pn[0] == 'd' && strncmp (tn, "dmacc", 5) == 0)
! 		min_nops = 1;
  
  	      /* Errata 24 - MT{LO,HI} after [D]MACC */
  	      if (strcmp (tn, "mtlo") == 0
  		  || strcmp (tn, "mthi") == 0)
! 		min_nops = 1;
  	    }
! 	  else if (strncmp (pn, "dmult", 5) == 0
! 		   && (strncmp (tn, "dmult", 5) == 0
! 		       || strncmp (tn, "dmacc", 5) == 0))
  	    {
  	      /* Here is the rest of errata 23.  */
  	      min_nops = 1;
  	    }
+ 	  else if ((strncmp (pn, "dmult", 5) == 0 || strstr (pn, "div"))
+ 		   && (strncmp (tn, "macc", 4) == 0
+ 		       || strncmp (tn, "dmacc", 5) == 0))
+ 	    {
+ 	      /* VR4181A errata MD(4): "If a MACC or DMACC instruction is
+ 		 executed immediately after a DMULT, DMULTU, DIV, DIVU,
+ 		 DDIV or DDIVU instruction, the result of the MACC or
+ 		 DMACC instruction is incorrect.".  This partly overlaps
+ 		 the workaround for errata 23.  */
+ 	      min_nops = 1;
+ 	    }
  	  if (nops < min_nops)
  	    nops = min_nops;
  	}
*************** mips_emit_delays (bfd_boolean insns)
*** 2827,2838 ****
  	{
  	  int min_nops = 0;
  	  const char *pn = prev_insn.insn_mo->name;
! 	  if (strncmp(pn, "macc", 4) == 0
! 	      || strncmp(pn, "dmacc", 5) == 0
! 	      || strncmp(pn, "dmult", 5) == 0)
! 	    {
! 	      min_nops = 1;
! 	    }
  	  if (nops < min_nops)
  	    nops = min_nops;
  	}
--- 2838,2848 ----
  	{
  	  int min_nops = 0;
  	  const char *pn = prev_insn.insn_mo->name;
! 	  if (strncmp (pn, "macc", 4) == 0
! 	      || strncmp (pn, "dmacc", 5) == 0
! 	      || strncmp (pn, "dmult", 5) == 0
! 	      || strstr (pn, "div"))
! 	    min_nops = 1;
  	  if (nops < min_nops)
  	    nops = min_nops;
  	}
Index: testsuite/gas/mips/vr4122.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/vr4122.s,v
retrieving revision 1.2
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.2 vr4122.s
*** testsuite/gas/mips/vr4122.s	14 Apr 2004 07:48:49 -0000	1.2
--- testsuite/gas/mips/vr4122.s	7 May 2004 13:15:00 -0000
*************** r24:
*** 63,65 ****
--- 63,147 ----
  
  	dmacc	$4,$5,$6
  	mthi	$7
+ 
+ vr4181a_md1:
+ 	macc	$4,$5,$6
+ 	mult	$4,$5
+ 	or	$4,$5
+ 
+ 	macc	$4,$5,$6
+ 	multu	$4,$5
+ 	or	$4,$5
+ 
+ 	macc	$4,$5,$6
+ 	dmult	$4,$5
+ 	or	$4,$5
+ 
+ 	macc	$4,$5,$6
+ 	dmultu	$4,$5
+ 	or	$4,$5
+ 
+ 	dmacc	$4,$5,$6
+ 	mult	$4,$5
+ 	or	$4,$5
+ 
+ 	dmacc	$4,$5,$6
+ 	multu	$4,$5
+ 	or	$4,$5
+ 
+ 	dmacc	$4,$5,$6
+ 	dmult	$4,$5
+ 	or	$4,$5
+ 
+ 	dmacc	$4,$5,$6
+ 	dmultu	$4,$5
+ 	or	$4,$5
+ 
+ vr4181a_md4:
+ 	dmult	$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	dmultu	$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	div	$0,$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	divu	$0,$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	ddiv	$0,$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	ddivu	$0,$4,$5
+ 	macc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	dmult	$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	dmultu	$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	div	$0,$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	divu	$0,$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	ddiv	$0,$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
+ 
+ 	ddivu	$0,$4,$5
+ 	dmacc	$4,$5,$6
+ 	or	$4,$5
Index: testsuite/gas/mips/vr4122.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/vr4122.d,v
retrieving revision 1.3
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.3 vr4122.d
*** testsuite/gas/mips/vr4122.d	14 Apr 2004 07:48:49 -0000	1.3
--- testsuite/gas/mips/vr4122.d	7 May 2004 13:15:00 -0000
*************** 0+00e0 <[^>]*> mthi	a3
*** 65,68 ****
--- 65,172 ----
  0+00e4 <[^>]*> dmacc	a0,a1,a2
  0+00e8 <[^>]*> nop
  0+00ec <[^>]*> mthi	a3
+ #
+ # vr4181a_md1:
+ #
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> mult	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> multu	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> dmult	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> dmultu	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> mult	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> multu	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> dmult	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> nop
+ .* <[^>]*> dmultu	a0,a1
+ .* <[^>]*> or	a0,a0,a1
+ #
+ # vr4181a_md4:
+ #
+ .* <[^>]*> dmult	a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmultu	a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> div	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> divu	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> ddiv	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> ddivu	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> macc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmult	a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> dmultu	a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> div	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> divu	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> ddiv	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
+ #
+ .* <[^>]*> ddivu	zero,a0,a1
+ .* <[^>]*> nop
+ .* <[^>]*> dmacc	a0,a1,a2
+ .* <[^>]*> or	a0,a0,a1
  #...



More information about the Binutils mailing list