aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-mips.c33
-rw-r--r--gas/doc/as.texinfo6
-rw-r--r--gas/doc/c-mips.texi5
-rw-r--r--gas/testsuite/ChangeLog10
-rw-r--r--gas/testsuite/gas/mips/fix-rm7000-1.d22
-rw-r--r--gas/testsuite/gas/mips/fix-rm7000-1.s10
-rw-r--r--gas/testsuite/gas/mips/fix-rm7000-2.d57
-rw-r--r--gas/testsuite/gas/mips/fix-rm7000-2.s25
-rw-r--r--gas/testsuite/gas/mips/micromips@fix-rm7000-1.d16
-rw-r--r--gas/testsuite/gas/mips/micromips@fix-rm7000-2.d31
-rw-r--r--gas/testsuite/gas/mips/mips.exp4
12 files changed, 230 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3813336..94c2d58 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2013-11-19 Catherine Moore <clm@codesourcery.com>
+
+ * 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.
+
2013-11-19 Alexey Makhalov <makhaloff@gmail.com>
PR gas/16109
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;
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 9843574..5fe06e6 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -417,6 +417,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mmcu}] [@b{-mno-mcu}]
[@b{-minsn32}] [@b{-mno-insn32}]
[@b{-mfix7000}] [@b{-mno-fix7000}]
+ [@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
[@b{-mfix-vr4120}] [@b{-mno-fix-vr4120}]
[@b{-mfix-vr4130}] [@b{-mno-fix-vr4130}]
[@b{-mdebug}] [@b{-no-mdebug}]
@@ -1270,6 +1271,11 @@ Schedule and tune for a particular MIPS CPU.
Cause nops to be inserted if the read of the destination register
of an mfhi or mflo instruction occurs in the following two instructions.
+@item -mfix-rm7000
+@itemx -mno-fix-rm7000
+Cause nops to be inserted if a dmult or dmultu instruction is
+followed by a load instruction.
+
@item -mdebug
@itemx -no-mdebug
Cause stabs-style debugging output to go into an ECOFF-style .mdebug
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7927893..dfada1e 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -206,6 +206,11 @@ selected, allowing all instructions to be used.
Cause nops to be inserted if the read of the destination register
of an mfhi or mflo instruction occurs in the following two instructions.
+@item -mfix-rm7000
+@itemx -mno-fix-rm7000
+Cause nops to be inserted if a dmult or dmultu instruction is
+followed by a load instruction.
+
@item -mfix-loongson2f-jump
@itemx -mno-fix-loongson2f-jump
Eliminate instruction fetch from outside 256M region to work around the
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 1d38ed2..4d8e7de 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2013-11-19 Catherine Moore <clm@codesourcery.com>
+
+ * 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.
+
2013-11-18 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/avx512f-nondef.d: Updated for mingw.
diff --git a/gas/testsuite/gas/mips/fix-rm7000-1.d b/gas/testsuite/gas/mips/fix-rm7000-1.d
new file mode 100644
index 0000000..30765f6
--- /dev/null
+++ b/gas/testsuite/gas/mips/fix-rm7000-1.d
@@ -0,0 +1,22 @@
+#as: -mfix-rm7000 -mgp64 -mabi=64
+#objdump: -dz --prefix-addresses
+#name: MIPS RM7000 workarounds test 1
+#source: fix-rm7000-1.s
+
+.*file format.*
+
+Disassembly.*
+
+0+0000 <[^>]*> move v0,a0
+0+0004 <[^>]*> dmult a2,v1
+0+0008 <[^>]*> nop
+0+000c <[^>]*> nop
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> ld a3,0\(s8\)
+0+0018 <[^>]*> ld a0,0\(s8\)
+0+001c <[^>]*> move a0,a3
+0+0020 <[^>]*> dmult v0,a3
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> nop
+0+002c <[^>]*> nop
+0+0030 <[^>]*> ld a0,0\(s8\)
diff --git a/gas/testsuite/gas/mips/fix-rm7000-1.s b/gas/testsuite/gas/mips/fix-rm7000-1.s
new file mode 100644
index 0000000..be7e597
--- /dev/null
+++ b/gas/testsuite/gas/mips/fix-rm7000-1.s
@@ -0,0 +1,10 @@
+ .section .text2, "ax", @progbits
+ .align 2
+test1:
+ move $2,$4
+ dmult $6,$3
+ ld $7,0($fp)
+ ld $4,0($fp)
+ move $4,$7
+ dmult $2,$7
+ ld $4,0($fp)
diff --git a/gas/testsuite/gas/mips/fix-rm7000-2.d b/gas/testsuite/gas/mips/fix-rm7000-2.d
new file mode 100644
index 0000000..3ec2817
--- /dev/null
+++ b/gas/testsuite/gas/mips/fix-rm7000-2.d
@@ -0,0 +1,57 @@
+#as: -mfix-rm7000
+#objdump: -dz --prefix-addresses
+#name: MIPS RM7000 workarounds test 2
+#source: fix-rm7000-2.s
+
+.*file format.*
+
+Disassembly.*
+0+0000 <[^>]*> move v0,a0
+0+0004 <[^>]*> dmultu a1,a3
+0+0008 <[^>]*> nop
+0+000c <[^>]*> nop
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> lb a0,0\(s8\)
+0+0018 <[^>]*> dmult a2,v1
+0+001c <[^>]*> nop
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> lbu a3,0\(s8\)
+0+002c <[^>]*> move v0,a0
+0+0030 <[^>]*> dmultu a1,a3
+0+0034 <[^>]*> addiu a0,s8,0
+0+0038 <[^>]*> move v0,a0
+0+003c <[^>]*> dmult a2,v1
+0+0040 <[^>]*> nop
+0+0044 <[^>]*> nop
+0+0048 <[^>]*> nop
+0+004c <[^>]*> lh a3,0\(s8\)
+0+0050 <[^>]*> dmultu a1,a3
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> nop
+0+005c <[^>]*> nop
+0+0060 <[^>]*> lhu a0,0\(s8\)
+0+0064 <[^>]*> dmult a2,v1
+0+0068 <[^>]*> nop
+0+006c <[^>]*> nop
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> ll a3,0\(s8\)
+0+0078 <[^>]*> dmultu a1,a3
+0+007c <[^>]*> nop
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> nop
+0+0088 <[^>]*> lld a0,0\(s8\)
+0+008c <[^>]*> dmultu a1,a3
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> nop
+0+009c <[^>]*> lw a0,0\(s8\)
+0+00a0 <[^>]*> dmult a2,v1
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> nop
+0+00ac <[^>]*> nop
+0+00b0 <[^>]*> lwr a3,0\(s8\)
+0+00b4 <[^>]*> dmultu a1,a3
+0+00b8 <[^>]*> nop
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/fix-rm7000-2.s b/gas/testsuite/gas/mips/fix-rm7000-2.s
new file mode 100644
index 0000000..9e9ab0a
--- /dev/null
+++ b/gas/testsuite/gas/mips/fix-rm7000-2.s
@@ -0,0 +1,25 @@
+ .section .text2, "ax", @progbits
+ .align 2
+test2:
+ move $2,$4
+ dmultu $5,$7
+ lb $4,0($fp)
+ dmult $6,$3
+ lbu $7,0($fp)
+ move $2,$4
+ dmultu $5,$7
+ lca $4,0($fp)
+ move $2,$4
+ dmult $6,$3
+ lh $7,0($fp)
+ dmultu $5,$7
+ lhu $4,0($fp)
+ dmult $6,$3
+ ll $7,0($fp)
+ dmultu $5,$7
+ lld $4,0($fp)
+ dmultu $5,$7
+ lw $4,0($fp)
+ dmult $6,$3
+ lwr $7,0($fp)
+ dmultu $5,$7
diff --git a/gas/testsuite/gas/mips/micromips@fix-rm7000-1.d b/gas/testsuite/gas/mips/micromips@fix-rm7000-1.d
new file mode 100644
index 0000000..9225fba
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@fix-rm7000-1.d
@@ -0,0 +1,16 @@
+#as: -mfix-rm7000 -mgp64 -mabi=64
+#objdump: -dz --prefix-addresses
+#name: MIPS RM7000 workarounds test 1
+#source: fix-rm7000-1.s
+
+.*file format.*
+
+Disassembly.*
+
+0+0000 <[^>]*> move v0,a0
+0+0002 <[^>]*> dmult a2,v1
+0+0006 <[^>]*> ld a3,0\(s8\)
+0+000a <[^>]*> ld a0,0\(s8\)
+0+000e <[^>]*> move a0,a3
+0+0010 <[^>]*> dmult v0,a3
+0+0014 <[^>]*> ld a0,0\(s8\)
diff --git a/gas/testsuite/gas/mips/micromips@fix-rm7000-2.d b/gas/testsuite/gas/mips/micromips@fix-rm7000-2.d
new file mode 100644
index 0000000..b95d615
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@fix-rm7000-2.d
@@ -0,0 +1,31 @@
+#as: -mfix-rm7000
+#objdump: -dz --prefix-addresses
+#name: MIPS RM7000 workarounds test 2
+#source: fix-rm7000-2.s
+
+.*file format.*
+
+Disassembly.*
+0+0000 <[^>]*> move v0,a0
+0+0002 <[^>]*> dmultu a1,a3
+0+0006 <[^>]*> lb a0,0\(s8\)
+0+000a <[^>]*> dmult a2,v1
+0+000e <[^>]*> lbu a3,0\(s8\)
+0+0012 <[^>]*> move v0,a0
+0+0014 <[^>]*> dmultu a1,a3
+0+0018 <[^>]*> addiu a0,s8,0
+0+001c <[^>]*> move v0,a0
+0+001e <[^>]*> dmult a2,v1
+0+0022 <[^>]*> lh a3,0\(s8\)
+0+0026 <[^>]*> dmultu a1,a3
+0+002a <[^>]*> lhu a0,0\(s8\)
+0+002e <[^>]*> dmult a2,v1
+0+0032 <[^>]*> ll a3,0\(s8\)
+0+0036 <[^>]*> dmultu a1,a3
+0+003a <[^>]*> lld a0,0\(s8\)
+0+003e <[^>]*> dmultu a1,a3
+0+0042 <[^>]*> lw a0,0\(s8\)
+0+0046 <[^>]*> dmult a2,v1
+0+004a <[^>]*> lwr a3,0\(s8\)
+0+004e <[^>]*> dmultu a1,a3
+0+0052 <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index d632c4f..121566a 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -529,6 +529,10 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "eret-1"
run_dump_test "eret-2"
run_dump_test "eret-3"
+ run_dump_test_arches "fix-rm7000-1" \
+ [mips_arch_list_matching mips3 !singlefloat]
+ run_dump_test_arches "fix-rm7000-2" \
+ [mips_arch_list_matching mips3 !singlefloat]
run_dump_test_arches "24k-branch-delay-1" \
[mips_arch_list_matching mips1]
run_dump_test_arches "24k-triple-stores-1" \