[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