diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2004-05-07 16:39:26 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2004-05-07 16:39:26 +0000 |
commit | 532c738a1337f8d9e8f90ff48c2acb37f4ef9e6c (patch) | |
tree | 96ba53e9214b5ea74ba61fb22f68548c07fdff46 /gas/config | |
parent | e4b17d5c7a6d8aed00816280dbed1f026b7be380 (diff) | |
download | gdb-532c738a1337f8d9e8f90ff48c2acb37f4ef9e6c.zip gdb-532c738a1337f8d9e8f90ff48c2acb37f4ef9e6c.tar.gz gdb-532c738a1337f8d9e8f90ff48c2acb37f4ef9e6c.tar.bz2 |
* config/tc-mips.c (append_insn, mips_emit_delays): Extend -mfix-vr4120
to cope with VR4181A errata MD(1) and MD(4).
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-mips.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 6f0db09..8d380e9 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1858,38 +1858,49 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, 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) + 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; - } + 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; - } + /* 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; - } - + min_nops = 1; } - else if (strncmp(pn, "dmult", 5) == 0 - && (strncmp(tn, "dmult", 5) == 0 - || strncmp(tn, "dmacc", 5) == 0)) + 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; } @@ -2827,12 +2838,11 @@ mips_emit_delays (bfd_boolean insns) { 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 (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; } |