This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Work around the NOP issue of Loongson2F


This is a patch to work around a possible cpu pipeline issue. Without
this, under extreme cases, cpu might deadlock.(e.g. some have seen this
with binutils 2.18, ld dies when compiling)

The changed instruction has no real effect since it does nothing except
an extra writing operation, which is the key to prevent issue. The issue
has been solved in latest processor batches.

2009-11-13 Wu Zhangjin <wuzhangjin@gmail.com>, Lemote Inc.

	* opcodes/mips-opc.c (loongson2f_nop_insn): New variable.
	(mips_builtin_opcodes): Add a NOP macro instruction
	* include/opcde/mips.h (loongson2f_nop_insn): Declare variable.
	(M_NOP): New enum.
	* gas/config/tc-mips.c (mips_fix_loongson2f_nop): New variable.
	(md_parse_option): Initialize mips_fix_loongson2f_nop when
	-mfix-loongson2f-nop/-mno-fix-loongson2f-nop is passed.
	(md_begin): Initialize nop_insn from loongson2f_nop_insn
	when mips_fix_loongson2f_nop is true.
	(macro): Expand the NOP macro to loongson2f_nop_insn when
	mips_fix_loongson2f_nop is true.
	* gas/doc/c-mips.texi: Document -mfix-loongson2f-nop
	* gas/testsuite/gas/mips/loongson-2f-2.s: New test of
	-mfix-loongson2f-nop.
	* gas/testsuite/gas/mips/loongson-2f-2.d: Likewise.
	* gas/testsuite/gas/mips/mips.exp: Run the loongson-2f-2 test.
---
 gas/ChangeLog                          |   11 +++++++++++
 gas/config/tc-mips.c                   |   32 +++++++++++++++++++++++++++++++-
 gas/doc/c-mips.texi                    |    5 +++++
 gas/testsuite/ChangeLog                |    6 ++++++
 gas/testsuite/gas/mips/loongson-2f-2.d |   11 +++++++++++
 gas/testsuite/gas/mips/loongson-2f-2.s |   10 ++++++++++
 gas/testsuite/gas/mips/mips.exp        |    1 +
 include/ChangeLog                      |    5 +++++
 include/opcode/mips.h                  |    2 ++
 opcodes/ChangeLog                      |    6 ++++++
 opcodes/mips-opc.c                     |    5 +++++
 11 files changed, 93 insertions(+), 1 deletions(-)
 create mode 100644 gas/testsuite/gas/mips/loongson-2f-2.d
 create mode 100644 gas/testsuite/gas/mips/loongson-2f-2.s

diff --git a/gas/ChangeLog b/gas/ChangeLog
index eb6cd26..d6e3d9f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,14 @@
+2009-11-13  Wu Zhangjin <wuzhangjin@gmail.com>  
+
+	* config/tc-mips.c (mips_fix_loongson2f_nop): New variable.
+	(md_parse_option): Initialize mips_fix_loongson2f_nop when
+	-mfix-loongson2f-nop/-mno-fix-loongson2f-nop is passed.
+	(md_begin): Initialize nop_insn from loongson2f_nop_insn
+	when mips_fix_loongson2f_nop is true.
+	(macro): Expand the NOP macro to loongson2f_nop_insn when
+	mips_fix_loongson2f_nop is true.
+	* doc/c-mips.texi: Document -mfix-loongson2f-nop
+
 2009-10-13  Alan Modra  <amodra@bigpond.net.au>
 	    H.J. Lu  <hongjiu.lu@intel.com>
 
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 1c96480..d69a4e2 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -772,6 +772,9 @@ static int mips_fix_vr4120;
 /* ...likewise -mfix-vr4130.  */
 static int mips_fix_vr4130;
 
+/* ...likewise -mfix-loongson2f-nop.  */
+static int mips_fix_loongson2f_nop;
+
 /* ...likewise -mfix-24k.  */
 static int mips_fix_24k;
 
@@ -1917,7 +1920,10 @@ md_begin (void)
 		broken = 1;
 	      if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
 		{
-		  create_insn (&nop_insn, mips_opcodes + i);
+		  if (mips_fix_loongson2f_nop)
+		    create_insn (&nop_insn, &loongson2f_nop_insn);
+		  else
+		    create_insn (&nop_insn, mips_opcodes + i);
 		  nop_insn.fixed_p = 1;
 		}
 	    }
@@ -7361,6 +7367,17 @@ macro (struct mips_cl_insn *ip)
       move_register (dreg, sreg);
       break;
 
+    case M_NOP:
+      if (mips_fix_loongson2f_nop) {
+	static int inserted = 0;
+	if (!inserted) {
+	  hash_jam(op_hash, "nop.at", (void *)&loongson2f_nop_insn);
+	  inserted = 1;
+	}
+        macro_build(NULL, "nop.at", "", 0);
+      }
+      break;
+
 #ifdef LOSING_COMPILER
     default:
       /* Try and see if this is a new itbl instruction.
@@ -11224,6 +11241,8 @@ enum options
     OPTION_NO_FIX_VR4120,
     OPTION_FIX_VR4130,
     OPTION_NO_FIX_VR4130,
+    OPTION_FIX_LOONGSON2F_NOP,
+    OPTION_NO_FIX_LOONGSON2F_NOP,
     OPTION_TRAP,
     OPTION_BREAK,
     OPTION_EB,
@@ -11312,6 +11331,8 @@ struct option md_longopts[] =
   {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120},
   {"mfix-vr4130",    no_argument, NULL, OPTION_FIX_VR4130},
   {"mno-fix-vr4130", no_argument, NULL, OPTION_NO_FIX_VR4130},
+  {"mfix-loongson2f-nop", no_argument, NULL, OPTION_FIX_LOONGSON2F_NOP},
+  {"mno-fix-loongson2f-nop", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_NOP},
   {"mfix-24k",    no_argument, NULL, OPTION_FIX_24K},
   {"mno-fix-24k", no_argument, NULL, OPTION_NO_FIX_24K},
 
@@ -11591,6 +11612,14 @@ md_parse_option (int c, char *arg)
       mips_fix_vr4130 = 0;
       break;
 
+    case OPTION_FIX_LOONGSON2F_NOP:
+      mips_fix_loongson2f_nop = 1;
+      break;
+
+    case OPTION_NO_FIX_LOONGSON2F_NOP:
+      mips_fix_loongson2f_nop = 0;
+      break;
+
     case OPTION_RELAX_BRANCH:
       mips_relax_branch = 1;
       break;
@@ -15525,6 +15554,7 @@ MIPS options:\n\
   fprintf (stream, _("\
 -mfix-vr4120		work around certain VR4120 errata\n\
 -mfix-vr4130		work around VR4130 mflo/mfhi errata\n\
+-mfix-loongson2f-nop	work around Loongson2F NOP errata\n\
 -mfix-24k		insert a nop after ERET and DERET instructions\n\
 -mgp32			use 32-bit GPRs, regardless of the chosen ISA\n\
 -mfp32			use 32-bit FPRs, regardless of the chosen ISA\n\
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 9ca7ebf..d1c57dd 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -182,6 +182,11 @@ all problems in hand-written assembler code.
 @itemx -no-mfix-vr4130
 Insert nops to work around the VR4130 @samp{mflo}/@samp{mfhi} errata.
 
+@item -mfix-loongson2f-nop
+@itemx -no-mfix-loongson2f-nop
+Replace nops by @code{or at,at,zero} to work around the Loongson2F @samp{nop}
+errata.
+
 @item -mfix-24k
 @itemx -no-mfix-24k
 Insert nops to work around the 24K @samp{eret}/@samp{deret} errata.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 694128f..5f33c5f 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-13  Wu Zhangjin <wuzhangjin@gmail.com>  
+
+	* gas/mips/loongson-2f-2.s: New test of -mfix-loongson2f-nop.
+	* gas/mips/loongson-2f-2.d: Likewise.
+	* gas/mips/mips.exp: Run the loongson-2f-2 test. 
+
 2009-10-02  Peter Bergner  <bergner@vnet.ibm.com>
 
 	* gas/ppc/476.s: New test.
diff --git a/gas/testsuite/gas/mips/loongson-2f-2.d b/gas/testsuite/gas/mips/loongson-2f-2.d
new file mode 100644
index 0000000..89117c9
--- /dev/null
+++ b/gas/testsuite/gas/mips/loongson-2f-2.d
@@ -0,0 +1,11 @@
+#as: -mfix-loongson2f-nop
+#objdump: -M reg-names=numeric -dr
+#name: ST Microelectronics Loongson-2F workarounds of nop issue 
+
+.*:     file format .*
+
+Disassembly of section .text:
+.*:	00200825 	move	\$1,\$1
+.*:   	10000001 	b	0xc
+.*:   	00200825 	move	\$1,\$1
+.*:	00200825 	move	\$1,\$1
diff --git a/gas/testsuite/gas/mips/loongson-2f-2.s b/gas/testsuite/gas/mips/loongson-2f-2.s
new file mode 100644
index 0000000..c4e0000
--- /dev/null
+++ b/gas/testsuite/gas/mips/loongson-2f-2.s
@@ -0,0 +1,10 @@
+# Test workarounds selected by -mfix-loongson2f-nop
+
+	.text
+	.set noreorder
+
+	nop
+	b	1f
+	nop
+1:
+	nop
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 6f82f46..c0a3c24 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -789,6 +789,7 @@ if { [istarget mips*-*-vxworks*] } {
 
     run_dump_test "loongson-2e"
     run_dump_test "loongson-2f"
+    run_dump_test "loongson-2f-2"
 
     run_dump_test_arches "octeon"	[mips_arch_list_matching octeon]
     run_list_test_arches "octeon-ill" "" \
diff --git a/include/ChangeLog b/include/ChangeLog
index 9e6fb59..006b0a6 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-13  Wu Zhangjin <wuzhangjin@gmail.com>  
+
+	* opcde/mips.h (loongson2f_nop_insn): Declare variable.
+	(M_NOP): New enum.
+
 2009-09-09  Martin Thuresson  <martin@mtme.org>
 
 	* bfdlink.h (struct bfd_link_hash_common_entry): Move to top
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index 27d10e6..f9e364a 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -825,6 +825,7 @@ enum
   M_MULO_I,
   M_MULOU,
   M_MULOU_I,
+  M_NOP,
   M_NOR_I,
   M_OR_I,
   M_REM_3,
@@ -1104,6 +1105,7 @@ extern int bfd_mips_num_opcodes;
    */
 
 extern const struct mips_opcode mips16_opcodes[];
+extern const struct mips_opcode loongson2f_nop_insn;
 extern const int bfd_mips16_num_opcodes;
 
 #endif /* _MIPS_H_ */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 535d450..f3aeb42 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-13  Wu Zhangjin <wuzhangjin@gmail.com>  
+
+	* mips-opc.c (loongson2f_nop_insn): New variable.
+	(mips_builtin_opcodes): Add a NOP macro instruction
+
+
 2009-10-06  Nick Clifton  <nickc@redhat.com>
 
 	* po/fi.po: Updated Finnish translation.
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index 6278a20..f79cb16 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -187,6 +187,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
 /* name,    args,	match,	    mask,	pinfo,          	pinfo2,		membership */
 {"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	0,		I4_32|G3	},
 {"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S,		0,		I4_33	},
+{"nop",     "",         0,          (int)M_NOP, INSN_MACRO,           	0,		I1      },
 {"nop",     "",         0x00000000, 0xffffffff, 0,              	INSN2_ALIAS,	I1      }, /* sll */
 {"ssnop",   "",         0x00000040, 0xffffffff, 0,              	INSN2_ALIAS,	I32|N55	}, /* sll */
 {"ehb",     "",         0x000000c0, 0xffffffff, 0,              	INSN2_ALIAS,	I33	}, /* sll */
@@ -1987,6 +1988,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1	}
 };
 
+/* Work around a possible cpu pipeline issue of Loongson2F */
+const struct mips_opcode loongson2f_nop_insn =
+{"nop.at",     "",         0x00200825, 0xffffffff, 0,              	INSN2_ALIAS,	I1    }; /* or at,at,zero */
+
 #define MIPS_NUM_OPCODES \
 	((sizeof mips_builtin_opcodes) / (sizeof (mips_builtin_opcodes[0])))
 const int bfd_mips_num_builtin_opcodes = MIPS_NUM_OPCODES;
-- 
1.6.2.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]