This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

Blackfin: Workaround for indirect calls hardware anomaly


This works around a hardware anomaly that can cause indirect calls to go
to the wrong target.  This only happens when ICPLBs (memory protection)
aren't enabled, so there's a new switch, -micplb, which defaults to on
for Linux targets.


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 142238)
+++ ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2008-11-04  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+	* config/bfin/bfin.opt (micplb): New option.
+	* config/bfin/linux.h (SUBTARGET_DRIVER_SELF_SPECS): Set it.
+	* config/bfin/bfin-protos.h (WA_INDIRECT_CALLS,
+	ENABLE_WA_INDIRECT_CALLS): New macros.
+	* config/bfin/bfin.c (bfin_cpus): Add WA_INDIRECT_CALLS to
+	all 54x CPUs.
+	(indirect_call_p): New function.
+	(workaround_speculation): Handle anomaly 05-00-0426 when
+	ENABLE_WA_INDIRECT_CALLS is true.
+	* config/bfin/bfin.h (TARGET_CPU_CPP_BUILTINS): Define
+	__WORKAROUND_INDIRECT_CALLS if ENABLE_WA_INDIRECT_CALLS.
+	* doc/invoke.texi (Blackfin Options): Document -micplb.
+
 2008-11-26  DJ Delorie  <dj@redhat.com>
 
 	* config/m32c/mov.md ("extendhipsi2"): New.
Index: config/bfin/bfin.opt
===================================================================
--- config/bfin/bfin.opt	(revision 142238)
+++ config/bfin/bfin.opt	(working copy)
@@ -95,3 +95,7 @@ Build for Core B
 msdram
 Target Report Mask(SDRAM)
 Build for SDRAM
+
+micplb
+Target Report Mask(ICPLB)
+Assume ICPLBs are enabled at runtime.
Index: config/bfin/linux.h
===================================================================
--- config/bfin/linux.h	(revision 142238)
+++ config/bfin/linux.h	(working copy)
@@ -1,6 +1,6 @@
 #undef SUBTARGET_DRIVER_SELF_SPECS
 #define SUBTARGET_DRIVER_SELF_SPECS \
-  "%{!mno-fdpic:-mfdpic}",
+  "%{!mno-fdpic:-mfdpic} -micplb",
 
 #undef TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
Index: config/bfin/bfin-protos.h
===================================================================
--- config/bfin/bfin-protos.h	(revision 142238)
+++ config/bfin/bfin-protos.h	(working copy)
@@ -75,6 +75,11 @@ extern unsigned int bfin_workarounds;
 #define ENABLE_WA_RETS \
   (bfin_workarounds & WA_RETS)
 
+/* For the anomaly 05-00-0426 */
+#define WA_INDIRECT_CALLS 0x00000008
+#define ENABLE_WA_INDIRECT_CALLS \
+  ((bfin_workarounds & WA_INDIRECT_CALLS) && !TARGET_ICPLB)
+
 #define WA_05000257 0x00000040
 #define ENABLE_WA_05000257 \
   (bfin_workarounds & WA_05000257)
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 142238)
+++ config/bfin/bfin.c	(working copy)
@@ -254,39 +254,39 @@ struct bfin_cpu bfin_cpus[] =
    | WA_05000283 | WA_05000257 | WA_05000315},
 
   {"bf542", BFIN_CPU_BF542, 0x0002,
-   WA_SPECULATIVE_LOADS},
+   WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
   {"bf542", BFIN_CPU_BF542, 0x0001,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
   {"bf542", BFIN_CPU_BF542, 0x0000,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
 
   {"bf544", BFIN_CPU_BF544, 0x0002,
-   WA_SPECULATIVE_LOADS},
+   WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
   {"bf544", BFIN_CPU_BF544, 0x0001,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
   {"bf544", BFIN_CPU_BF544, 0x0000,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
 
   {"bf547", BFIN_CPU_BF547, 0x0002,
-   WA_SPECULATIVE_LOADS},
+   WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
   {"bf547", BFIN_CPU_BF547, 0x0001,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
   {"bf547", BFIN_CPU_BF547, 0x0000,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
 
   {"bf548", BFIN_CPU_BF548, 0x0002,
-   WA_SPECULATIVE_LOADS},
+   WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
   {"bf548", BFIN_CPU_BF548, 0x0001,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
   {"bf548", BFIN_CPU_BF548, 0x0000,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
 
   {"bf549", BFIN_CPU_BF549, 0x0002,
-   WA_SPECULATIVE_LOADS},
+   WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
   {"bf549", BFIN_CPU_BF549, 0x0001,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
   {"bf549", BFIN_CPU_BF549, 0x0000,
-   WA_SPECULATIVE_LOADS | WA_RETS},
+   WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
 
   {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS
    | WA_05000283 | WA_05000315},
@@ -4921,6 +4921,22 @@ find_load (rtx insn)
   return NULL_RTX;
 }
 
+/* Determine whether PAT is an indirect call pattern.  */
+static bool
+indirect_call_p (rtx pat)
+{
+  if (GET_CODE (pat) == PARALLEL)
+    pat = XVECEXP (pat, 0, 0);
+  if (GET_CODE (pat) == SET)
+    pat = SET_SRC (pat);
+  gcc_assert (GET_CODE (pat) == CALL);
+  pat = XEXP (pat, 0);
+  gcc_assert (GET_CODE (pat) == MEM);
+  pat = XEXP (pat, 0);
+  
+  return REG_P (pat);
+}
+
 static void
 workaround_speculation (void)
 {
@@ -4929,7 +4945,8 @@ workaround_speculation (void)
   int cycles_since_jump = INT_MAX;
   int delay_added = 0;
 
-  if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS)
+  if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS
+      && ! ENABLE_WA_INDIRECT_CALLS)
     return;
 
   /* First pass: find predicted-false branches; if something after them
@@ -4962,6 +4979,15 @@ workaround_speculation (void)
 	  else
 	    cycles_since_jump = INT_MAX;
 	}
+      else if (CALL_P (insn))
+	{
+	  if (cycles_since_jump < INT_MAX)
+	    cycles_since_jump++;
+	  if (indirect_call_p (pat) && ENABLE_WA_INDIRECT_CALLS)
+	    {
+	      delay_needed = 3;
+	    }
+	}
       else if (INSN_P (insn))
 	{
 	  rtx load_insn = find_load (insn);
Index: config/bfin/bfin.h
===================================================================
--- config/bfin/bfin.h	(revision 142238)
+++ config/bfin/bfin.h	(working copy)
@@ -149,8 +149,10 @@ extern int target_flags;
 	builtin_define ("__WORKAROUND_SPECULATIVE_LOADS");		\
       if (ENABLE_WA_SPECULATIVE_SYNCS)					\
 	builtin_define ("__WORKAROUND_SPECULATIVE_SYNCS");		\
+      if (ENABLE_WA_INDIRECT_CALLS)					\
+	builtin_define ("__WORKAROUND_INDIRECT_CALLS");			\
       if (ENABLE_WA_RETS)						\
-	builtin_define ("__WORKAROUND_RETS");		\
+	builtin_define ("__WORKAROUND_RETS");				\
 						\
       if (TARGET_FDPIC)				\
 	{					\
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 142238)
+++ doc/invoke.texi	(working copy)
@@ -468,7 +468,8 @@ Objective-C and Objective-C++ Dialects}.
 -mno-id-shared-library  -mshared-library-id=@var{n} @gol
 -mleaf-id-shared-library  -mno-leaf-id-shared-library @gol
 -msep-data  -mno-sep-data  -mlong-calls  -mno-long-calls @gol
--mfast-fp -minline-plt -mmulticore  -mcorea  -mcoreb  -msdram}
+-mfast-fp -minline-plt -mmulticore  -mcorea  -mcoreb  -msdram @gol
+-micplb}
 
 @emph{CRIS Options}
 @gccoptlist{-mcpu=@var{cpu}  -march=@var{cpu}  -mtune=@var{cpu} @gol
@@ -9312,6 +9313,12 @@ Build standalone application for SDRAM. 
 link scripts will be used to put the application into SDRAM.
 Loader should initialize SDRAM before loading the application
 into SDRAM. This option defines @code{__BFIN_SDRAM}.
+
+@item -micplb
+@opindex micplb
+Assume that ICPLBs are enabled at runtime.  This has an effect on certain
+anomaly workarounds.  For Linux targets, the default is to assume ICPLBs
+are enabled; for standalone applications the default is off.
 @end table
 
 @node CRIS Options

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