diff options
author | Catherine Moore <clm@codesourcery.com> | 2013-11-19 04:44:59 -0800 |
---|---|---|
committer | Catherine Moore <clm@codesourcery.com> | 2013-11-19 05:07:54 -0800 |
commit | a8d14a88922c353d99250521a4fd2129a49b7810 (patch) | |
tree | 80ed0c332fa892d7ad7276620fd68ec3dfdc6a2b /gas/config | |
parent | cf3f45fad7811e89d6b586a1a429a314e3db9f53 (diff) | |
download | gdb-a8d14a88922c353d99250521a4fd2129a49b7810.zip gdb-a8d14a88922c353d99250521a4fd2129a49b7810.tar.gz gdb-a8d14a88922c353d99250521a4fd2129a49b7810.tar.bz2 |
2013-11-19 Catherine Moore <clm@codesourcery.com>
gas/
* config/tc-mips.c (mips_fix_pmc_rm7000): Declare.
(options): Add OPTION_FIX_PMC_RM7000 and OPTION_NO_FIX_PMC_RM7000.
(md_longopts): Add mfix-pmc-rm7000 and mno-fix-pmc-rm7000.
(INSN_DMULT): Define.
(INSN_DMULTU): Define.
(insns_between): Detect PMC RM7000 errata.
(md_parse_option): Supprt OPTION_FIX_PMC_RM7000 and
OPTION_NO_FIX_PMC_RM7000.
* doc/as.texinfo: Document new options.
* doc/c-mips.texi: Likewise.
gas/testsuite/
* gas/mips/fix-pmc-rm7000-1.d: New.
* gas/mips/fix-pmc-rm7000-1.s: New.
* gas/mips/fix-pmc-rm7000-2.d: New.
* gas/mips/fix-pmc-rm7000-2.s: New.
* gas/mips/micromips@fix-pmc-rm7000-1.d: New.
* gas/mips/micromips@fix-pmc-rm7000-2.d: New.
* gas/mips/mips.exp: Run new tests.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-mips.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index fcf06ac..34f1bf0 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -865,6 +865,9 @@ static int mips_fix_vr4130; /* ...likewise -mfix-24k. */ static int mips_fix_24k; +/* ...likewise -mfix-rm7000 */ +static int mips_fix_rm7000; + /* ...likewise -mfix-cn63xxp1 */ static bfd_boolean mips_fix_cn63xxp1; @@ -1354,6 +1357,8 @@ enum options OPTION_MNO_7000_HILO_FIX, OPTION_FIX_24K, OPTION_NO_FIX_24K, + OPTION_FIX_RM7000, + OPTION_NO_FIX_RM7000, OPTION_FIX_LOONGSON2F_JUMP, OPTION_NO_FIX_LOONGSON2F_JUMP, OPTION_FIX_LOONGSON2F_NOP, @@ -1469,6 +1474,8 @@ struct option md_longopts[] = {"mno-fix-vr4130", no_argument, NULL, OPTION_NO_FIX_VR4130}, {"mfix-24k", no_argument, NULL, OPTION_FIX_24K}, {"mno-fix-24k", no_argument, NULL, OPTION_NO_FIX_24K}, + {"mfix-rm7000", no_argument, NULL, OPTION_FIX_RM7000}, + {"mno-fix-rm7000", no_argument, NULL, OPTION_NO_FIX_RM7000}, {"mfix-cn63xxp1", no_argument, NULL, OPTION_FIX_CN63XXP1}, {"mno-fix-cn63xxp1", no_argument, NULL, OPTION_NO_FIX_CN63XXP1}, @@ -5559,8 +5566,10 @@ classify_vr4120_insn (const char *name) return NUM_FIX_VR4120_CLASSES; } -#define INSN_ERET 0x42000018 -#define INSN_DERET 0x4200001f +#define INSN_ERET 0x42000018 +#define INSN_DERET 0x4200001f +#define INSN_DMULT 0x1c +#define INSN_DMULTU 0x1d /* Return the number of instructions that must separate INSN1 and INSN2, where INSN1 is the earlier instruction. Return the worst-case value @@ -5611,6 +5620,18 @@ insns_between (const struct mips_cl_insn *insn1, } } + /* If we're working around PMC RM7000 errata, there must be three + nops between a dmult and a load instruction. */ + if (mips_fix_rm7000 && !mips_opts.micromips) + { + if ((insn1->insn_opcode & insn1->insn_mo->mask) == INSN_DMULT + || (insn1->insn_opcode & insn1->insn_mo->mask) == INSN_DMULTU) + { + if (pinfo2 & INSN_LOAD_MEMORY) + return 3; + } + } + /* If working around VR4120 errata, check for combinations that need a single intervening instruction. */ if (mips_fix_vr4120 && !mips_opts.micromips) @@ -13592,6 +13613,14 @@ md_parse_option (int c, char *arg) mips_fix_24k = 0; break; + case OPTION_FIX_RM7000: + mips_fix_rm7000 = 1; + break; + + case OPTION_NO_FIX_RM7000: + mips_fix_rm7000 = 0; + break; + case OPTION_FIX_LOONGSON2F_JUMP: mips_fix_loongson2f_jump = TRUE; break; |