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]

Re: [PATCH v1] Add Loongson2F specific NOP instruction


Hi, Richard

Thanks very much for your feedback, what about this one?

Herein, I use "addu at,at,zero"(move at,at) as a work around, have
tested it with gcc 4.5 on the linux kernel 2.6.32-rc7.

Best Regards,
	Wu Zhangjin

On Sat, 2009-11-14 at 12:47 +0000, Richard Sandiford wrote:
> Wu Zhangjin <wuzhangjin@gmail.com> writes:
> > I'm sorry, "addu v0,zero,v0" may make kernel hang at "ld      a0,0(v0)",
> > I need to change it be something else.
> 
> Also, workarounds like this should generally be under the control
> of an -mfix-* option, so that you can get them even when compiling
> without -march=loongson*.  For example, a distributor might want
> to compile code that runs on both Loongson and non-Loongson
> architectures while still avoiding this errata.  (This is how
> errata on other MIPS processors are handled.)
> 
> Of course, the likelihood of a distributor doing this depends on whether
> the errata only affects kernel code.  But then there are two cases:
> 
>   - if the errata can only happen in the kernel, we might want
>     to compile userspace normally, since I imagine using non-zero
>     registers would introduce false pipeline hazards.  -mfix-* would
>     be useful to distinguish between kernel and userspace code.
> 
>   - if the errata can happen in userspace, -mfix-* would be useful
>     to distributors.
> 
> It's OK for -march=loongson* to imply -mfix-*, if that seems appropriate.
> -march=loongson* musn't trump an explicit -mno-fix-* though.
> 
> Any patch along those lines will need a copyright assignment.  Do you
> (or your employer) have one on file?
> 
> Richard

>From 1e05bca3727a6b826b45bdea7c00c7229514060b Mon Sep 17 00:00:00 2001
From: Wu Zhangjin <wuzhangjin@gmail.com>
Date: Sun, 15 Nov 2009 15:04:26 +0800
Subject: [PATCH] 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.

	* gas/config/tc-mips.c: define ls2f_builtin_nop, use "addu
	at,at,zero" instead of "nop" as a work around.
	* include/opcde/mips.h: declare ls2f_builtin_nop.
	* mips-opc.c (mips_builtin_opcodes): define mips_fix_ls2f_nop,
	Use ls2f_builtin_nop instead of the generic nop if fix-ls2f-nop
	is enabled.
---
 gas/config/tc-mips.c  |   21 ++++++++++++++++++++-
 include/opcode/mips.h |    1 +
 opcodes/mips-opc.c    |    4 ++++
 3 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 1c96480..a804cfc 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-ls2f-nop.  */
+static int mips_fix_ls2f_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_ls2f_nop)
+			  create_insn (&nop_insn, &ls2f_builtin_nop);
+		  else
+			  create_insn (&nop_insn, mips_opcodes + i);
 		  nop_insn.fixed_p = 1;
 		}
 	    }
@@ -11224,6 +11230,8 @@ enum options
     OPTION_NO_FIX_VR4120,
     OPTION_FIX_VR4130,
     OPTION_NO_FIX_VR4130,
+    OPTION_FIX_LS2F_NOP,
+    OPTION_NO_FIX_LS2F_NOP,
     OPTION_TRAP,
     OPTION_BREAK,
     OPTION_EB,
@@ -11312,6 +11320,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-ls2f-nop", no_argument, NULL, OPTION_FIX_LS2F_NOP},
+  {"mno-fix-ls2f-nop", no_argument, NULL, OPTION_NO_FIX_LS2F_NOP},
   {"mfix-24k",    no_argument, NULL, OPTION_FIX_24K},
   {"mno-fix-24k", no_argument, NULL, OPTION_NO_FIX_24K},
 
@@ -11591,6 +11601,14 @@ md_parse_option (int c, char *arg)
       mips_fix_vr4130 = 0;
       break;
 
+    case OPTION_FIX_LS2F_NOP:
+      mips_fix_ls2f_nop = 1;
+      break;
+
+    case OPTION_NO_FIX_LS2F_NOP:
+      mips_fix_ls2f_nop = 0;
+      break;
+
     case OPTION_RELAX_BRANCH:
       mips_relax_branch = 1;
       break;
@@ -15525,6 +15543,7 @@ MIPS options:\n\
   fprintf (stream, _("\
 -mfix-vr4120		work around certain VR4120 errata\n\
 -mfix-vr4130		work around VR4130 mflo/mfhi errata\n\
+-mfix-ls2f-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/include/opcode/mips.h b/include/opcode/mips.h
index 27d10e6..4f845ad 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -1104,6 +1104,7 @@ extern int bfd_mips_num_opcodes;
    */
 
 extern const struct mips_opcode mips16_opcodes[];
+extern const struct mips_opcode ls2f_builtin_nop;
 extern const int bfd_mips16_num_opcodes;
 
 #endif /* _MIPS_H_ */
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index 6278a20..70fbaeb 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -1987,6 +1987,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 ls2f_builtin_nop =
+{"nop",     "",         0x00200821, 0xffffffff, 0,              	INSN2_ALIAS,	I1    }; /* addu 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]