[PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug

2021-09-15 Thread Daniel Cederman
From: Andreas Larsson 

gcc/ChangeLog:

* config/sparc/sparc.c (dump_target_flag_bits): Print bit names for
LEON and LEON3.
---
 gcc/config/sparc/sparc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 06f41d7bb53..d5a0ff7d4ea 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1596,6 +1596,10 @@ dump_target_flag_bits (const int flags)
 fprintf (stderr, "CBCOND ");
   if (flags & MASK_DEPRECATED_V8_INSNS)
 fprintf (stderr, "DEPRECATED_V8_INSNS ");
+  if (flags & MASK_LEON)
+fprintf (stderr, "LEON ");
+  if (flags & MASK_LEON3)
+fprintf (stderr, "LEON3 ");
   if (flags & MASK_SPARCLET)
 fprintf (stderr, "SPARCLET ");
   if (flags & MASK_SPARCLITE)
-- 
2.25.1



[PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds

2021-09-15 Thread Daniel Cederman
Check the attribute of instruction to determine if it performs a store
or load operation. This more generic approach sees the last instruction
in the GOTdata_op model as a potential load and treats the memory barrier
as a potential store instruction.

gcc/ChangeLog:

* config/sparc/sparc.c (store_insn_p): Add predicate for store
attributes.
(load_insn_p): Add predicate for load attributes.
(sparc_do_work_around_errata): Use new predicates.
---
 gcc/config/sparc/sparc.c | 37 +
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d5a0ff7d4ea..fa78e0dc739 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1045,6 +1045,31 @@ atomic_insn_for_leon3_p (rtx_insn *insn)
 }
 }
 
+/* True if INSN is a store instruction.  */
+
+static bool
+store_insn_p (rtx_insn *insn)
+{
+   if (GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+   return (get_attr_type (insn) == TYPE_STORE)
+ || (get_attr_type (insn) == TYPE_FPSTORE);
+}
+
+/* True if INSN is a load instruction.  */
+
+static bool
+load_insn_p (rtx_insn *insn)
+{
+   if (GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+   return (get_attr_type (insn) == TYPE_LOAD)
+ || (get_attr_type (insn) == TYPE_SLOAD)
+ || (get_attr_type (insn) == TYPE_FPLOAD);
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -1105,9 +1130,7 @@ sparc_do_work_around_errata (void)
 instruction at branch target.  */
   if (sparc_fix_ut700
  && NONJUMP_INSN_P (insn)
- && (set = single_set (insn)) != NULL_RTX
- && mem_ref (SET_SRC (set))
- && REG_P (SET_DEST (set)))
+ && load_insn_p (insn))
{
  if (jump && jump_to_label_p (jump))
{
@@ -1212,7 +1235,7 @@ sparc_do_work_around_errata (void)
   if (sparc_fix_b2bst
  && NONJUMP_INSN_P (insn)
  && (set = single_set (insn)) != NULL_RTX
- && MEM_P (SET_DEST (set)))
+ && store_insn_p (insn))
{
  /* Sequence B begins with a double-word store.  */
  bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
@@ -1245,8 +1268,7 @@ sparc_do_work_around_errata (void)
  if (seq_b)
{
  /* Add NOP if followed by a store.  */
- if ((set = single_set (after)) != NULL_RTX
- && MEM_P (SET_DEST (set)))
+ if (store_insn_p (after))
insert_nop = true;
 
  /* Otherwise it is ok.  */
@@ -1268,8 +1290,7 @@ sparc_do_work_around_errata (void)
 
  /* Add NOP if third instruction is a store.  */
  if (i == 1
- && (set = single_set (after)) != NULL_RTX
- && MEM_P (SET_DEST (set)))
+ && store_insn_p (after))
insert_nop = true;
}
}
-- 
2.25.1



[PATCH 2/4] sparc: Skip all empty assembly statements

2021-09-15 Thread Daniel Cederman
This version detects multiple empty assembly statements in a row and also
detects non-memory barrier empty assembly statements (__asm__("")). It
can be used instead of next_active_insn().

gcc/ChangeLog:

* config/sparc/sparc.c (next_active_non_empty_insn): New function
that returns next active non empty assembly instruction.
(sparc_do_work_around_errata): Use new function.
---
 gcc/config/sparc/sparc.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index fa78e0dc739..b087c5b3fc8 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1082,6 +1082,26 @@ load_insn_p (rtx_insn *insn)
&& GET_CODE (PATTERN (INSN)) != USE \
&& GET_CODE (PATTERN (INSN)) != CLOBBER)
 
+rtx_insn *
+next_active_non_empty_insn (rtx_insn *insn)
+{
+  insn = next_active_insn (insn);
+
+  while (insn
+&& ((GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE)
+|| (GET_CODE (PATTERN (insn)) == ASM_INPUT)
+|| (USEFUL_INSN_P (insn)
+&& (asm_noperands (PATTERN (insn))>=0)
+&& !strcmp (decode_asm_operands (PATTERN (insn),
+ NULL, NULL, NULL,
+ NULL, NULL), ""
+{
+  insn = next_active_insn (insn);
+}
+
+  return insn;
+}
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -1139,7 +1159,7 @@ sparc_do_work_around_errata (void)
emit_insn_before (gen_nop (), target);
}
 
- next = next_active_insn (insn);
+ next = next_active_non_empty_insn (insn);
  if (!next)
break;
 
@@ -1242,23 +1262,12 @@ sparc_do_work_around_errata (void)
  rtx_insn *after;
  int i;
 
- next = next_active_insn (insn);
+ next = next_active_non_empty_insn (insn);
  if (!next)
break;
 
  for (after = next, i = 0; i < 2; i++)
{
- /* Skip empty assembly statements.  */
- if ((GET_CODE (PATTERN (after)) == UNSPEC_VOLATILE)
- || (USEFUL_INSN_P (after)
- && (asm_noperands (PATTERN (after))>=0)
- && !strcmp (decode_asm_operands (PATTERN (after),
-  NULL, NULL, NULL,
-  NULL, NULL), "")))
-   after = next_active_insn (after);
- if (!after)
-   break;
-
  /* If the insn is a branch, then it cannot be problematic.  */
  if (!NONJUMP_INSN_P (after)
  || GET_CODE (PATTERN (after)) == SEQUENCE)
@@ -1283,7 +1292,7 @@ sparc_do_work_around_errata (void)
  && (MEM_P (SET_DEST (set)) || mem_ref (SET_SRC (set
break;
 
- after = next_active_insn (after);
+ after = next_active_non_empty_insn (after);
  if (!after)
break;
}
-- 
2.25.1



[PATCH] sparc: Add scheduling information for LEON5

2021-09-15 Thread Daniel Cederman
The LEON5 can often dual issue instructions from the same 64-bit aligned
double word if there are no data dependencies. Add scheduling information
to avoid scheduling unpairable instructions back-to-back.

gcc/ChangeLog:

* config/sparc/sparc-opts.h (enum sparc_processor_type): Add LEON5
* config/sparc/sparc.c (struct processor_costs): Add LEON5 costs
(leon5_adjust_cost): Increase cost of store with data dependency
on ALU instruction and FPU anti-dependencies.
(sparc_option_override): Add LEON5 costs
(sparc_adjust_cost): Add LEON5 cost adjustments
* config/sparc/sparc.h: Add LEON5
* config/sparc/sparc.md: Include LEON5 scheduling information
* config/sparc/sparc.opt: Add LEON5
* doc/invoke.texi: Add LEON5
* config/sparc/leon5.md: New file.
---
 gcc/config/sparc/leon5.md | 103 ++
 gcc/config/sparc/sparc-opts.h |   1 +
 gcc/config/sparc/sparc.c  |  84 +++
 gcc/config/sparc/sparc.h  |  36 ++--
 gcc/config/sparc/sparc.md |   2 +
 gcc/config/sparc/sparc.opt|   3 +
 gcc/doc/invoke.texi   |  13 +++--
 7 files changed, 220 insertions(+), 22 deletions(-)
 create mode 100644 gcc/config/sparc/leon5.md

diff --git a/gcc/config/sparc/leon5.md b/gcc/config/sparc/leon5.md
new file mode 100644
index 000..3f72a9f53e0
--- /dev/null
+++ b/gcc/config/sparc/leon5.md
@@ -0,0 +1,103 @@
+;; Scheduling description for LEON5.
+;;   Copyright (C) 2021 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; .
+
+
+;; The LEON5 can often dual issue instructions from the same 64-bit aligned
+;; double word if there are no data dependencies.
+;;
+;; Avoid scheduling load/store, FPU, and multiplication instructions back to
+;; back, regardless of data dependencies.
+;;
+;; Push comparisons away from the associated branch instruction.
+;;
+;; Avoid scheduling ALU instructions with data dependencies back to back.
+;;
+;; Schedule three instructions between load and dependant instruction.
+
+(define_automaton "leon5")
+
+(define_cpu_unit "leon5_memory" "leon5")
+(define_cpu_unit "leon5_mul" "leon5")
+(define_cpu_unit "grfpu_d" "grfpu")
+(define_cpu_unit "grfpu_s" "grfpu")
+
+(define_insn_reservation "leon5_load" 4
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "load,sload"))
+  "leon5_memory * 2, nothing * 2")
+
+(define_insn_reservation "leon5_fpload" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpload"))
+  "leon5_memory * 2 + grfpu_alu * 2")
+
+(define_insn_reservation "leon5_store" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "store"))
+  "leon5_memory * 2")
+
+(define_insn_reservation "leon5_fpstore" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpstore"))
+  "leon5_memory * 2 + grfpu_alu * 2")
+
+(define_insn_reservation "leon5_ialu" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "ialu, shift, ialuX"))
+  "nothing * 2")
+
+(define_insn_reservation "leon5_compare" 5
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "compare"))
+  "nothing * 5")
+
+(define_insn_reservation "leon5_imul" 4
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "imul"))
+  "leon5_mul * 2, nothing * 2")
+
+(define_insn_reservation "leon5_idiv" 35
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "imul"))
+  "nothing * 35")
+
+(define_insn_reservation "leon5_fp_alu" 5
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fp,fpcmp,fpmul,fpmove"))
+  "grfpu_alu * 2, nothing*3")
+
+(define_insn_reservation "leon5_fp_divs" 17
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpdivs"))
+  "grfpu_alu * 2 + grfpu_d*16, nothing")
+
+(define_insn_reservation "leon5_fp_divd" 18
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpdivd"))
+  "grfpu_alu * 2 + grfpu_d*17, nothing")
+
+(define_insn_reservation "leon5_fp_sqrts" 25
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpsqrts"))
+  "grfpu_alu * 2 + grfpu_s*24, nothing")
+
+(define_insn_reservation "leon5_fp_sqrtd" 26
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpsqrtd"))
+  "grfpu_alu * 2 + grfpu_s*25, nothing")
diff --git a/gcc/config/sparc/sparc-opts.h b/gcc/config/sparc/sparc-opts.h
index 1af556e1156..9299cf6a2ff 100644
--- a/gcc/config/sparc/sparc-opts.h
+++ b/gcc/config/sparc/sparc-opts.h
@@ -31,6 +31,7 @@ enum sparc_processor_type {
   P

[PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700

2021-09-15 Thread Daniel Cederman
A call to the function might have a load instruction in the delay slot
and a load followed by an atomic function could cause a deadlock.

gcc/ChangeLog:

* config/sparc/sparc.c (sparc_do_work_around_errata): Do not begin
functions with atomic instruction in the UT700 errata workaround.
---
 gcc/config/sparc/sparc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index b087c5b3fc8..5177d48793d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1106,6 +1106,7 @@ static unsigned int
 sparc_do_work_around_errata (void)
 {
   rtx_insn *insn, *next;
+  bool find_first_useful = true;
 
   /* Force all instructions to be split into their final form.  */
   split_all_insns_noflow ();
@@ -1130,6 +1131,16 @@ sparc_do_work_around_errata (void)
   else
jump = NULL;
 
+  /* Do not begin function with atomic instruction.  */
+  if (sparc_fix_ut700
+ && find_first_useful
+ && USEFUL_INSN_P (insn))
+   {
+ find_first_useful = false;
+ if (atomic_insn_for_leon3_p (insn))
+   emit_insn_before (gen_nop (), insn);
+   }
+
   /* Place a NOP at the branch target of an integer branch if it is a
 floating-point operation or a floating-point branch.  */
   if (sparc_fix_gr712rc
-- 
2.25.1



[PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled

2021-09-15 Thread Daniel Cederman
This is needed to prevent the Store -> (Non-store or load) -> Store
sequence.

gcc/ChangeLog:

* config/sparc/sparc.md: Add NOP to prevent sensitive sequence for
B2BST errata workaround.
---
 gcc/config/sparc/sparc.md | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 24b76e0cacd..3ac074a244d 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -8353,9 +8353,15 @@ visl")
(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
(set (match_scratch:SI 2 "=&r") (const_int 0))]
   "TARGET_ARCH32"
-  "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
+{
+  if (sparc_fix_b2bst)
+return "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2\;nop";
+  else
+return "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2";
+}
   [(set_attr "type" "multi")
-   (set_attr "length" "3")])
+   (set (attr "length") (if_then_else (eq_attr "fix_b2bst" "true")
+ (const_int 4) (const_int 3)))])
 
 (define_insn "stack_protect_set64"
   [(set (match_operand:DI 0 "memory_operand" "=m")
-- 
2.25.1



Re: [PATCH] sparc: Add scheduling information for LEON5

2021-09-15 Thread Daniel Cederman
Thank you for reviewing the patches! I will address your comments and 
push the patches after testing.


Thanks again,
Daniel

On 2021-09-15 12:18, Eric Botcazou wrote:

The LEON5 can often dual issue instructions from the same 64-bit aligned
double word if there are no data dependencies. Add scheduling information
to avoid scheduling unpairable instructions back-to-back.

gcc/ChangeLog:

 * config/sparc/sparc-opts.h (enum sparc_processor_type): Add LEON5
 * config/sparc/sparc.c (struct processor_costs): Add LEON5 costs
 (leon5_adjust_cost): Increase cost of store with data dependency
 on ALU instruction and FPU anti-dependencies.
 (sparc_option_override): Add LEON5 costs
 (sparc_adjust_cost): Add LEON5 cost adjustments
 * config/sparc/sparc.h: Add LEON5
 * config/sparc/sparc.md: Include LEON5 scheduling information
 * config/sparc/sparc.opt: Add LEON5
 * doc/invoke.texi: Add LEON5
 * config/sparc/leon5.md: New file.

OK for whatever branches you deem relevant, modulo a couple of nits:


+;; Avoid scheduling load/store, FPU, and multiplication instructions back

and multiply instructions


+;; Schedule three instructions between load and dependant instruction.

dependent



[PATCH] libsanitizer: Replace memcpy with internal version in sanitizer_common

2024-01-16 Thread Daniel Cederman
When GCC is configured with --enable-target-optspace the compiler generates
a memcpy call in the Symbolizer constructor in sanitizer_symbolizer.cpp
when compiling for SPARC V8. Add HAVE_AS_SYM_ASSIGN to replace it with a
call to __sanitizer_internal_memcpy.

libsanitizer/ChangeLog:

* sanitizer_common/Makefile.am (DEFS): Add @AS_SYM_ASSIGN_DEFS@.
* sanitizer_common/Makefile.in: Regenerate.
---
 libsanitizer/sanitizer_common/Makefile.am | 2 +-
 libsanitizer/sanitizer_common/Makefile.in | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libsanitizer/sanitizer_common/Makefile.am 
b/libsanitizer/sanitizer_common/Makefile.am
index 02afe65620a2..9ed6ef88775a 100644
--- a/libsanitizer/sanitizer_common/Makefile.am
+++ b/libsanitizer/sanitizer_common/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir) 
-isystem $(top_srcdir)/i
 # May be used by toolexeclibdir.
 gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
 
-DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS @RPC_DEFS@
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS @RPC_DEFS@ @AS_SYM_ASSIGN_DEFS@
 AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic 
-Wno-long-long  -fPIC -fno-builtin -fno-exceptions -fno-rtti 
-fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros
 AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
 AM_CXXFLAGS += -std=gnu++14
diff --git a/libsanitizer/sanitizer_common/Makefile.in 
b/libsanitizer/sanitizer_common/Makefile.in
index 45141930f9fa..31fff8236fee 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -245,7 +245,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
-DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS @RPC_DEFS@
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS @RPC_DEFS@ @AS_SYM_ASSIGN_DEFS@
 DEPDIR = @DEPDIR@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
-- 
2.40.1



Re: [PATCH] libsanitizer: Replace memcpy with internal version in sanitizer_common

2024-01-17 Thread Daniel Cederman

On 2024-01-16 15:44, Jakub Jelinek wrote:

On Tue, Jan 16, 2024 at 03:11:39PM +0100, Daniel Cederman wrote:

When GCC is configured with --enable-target-optspace the compiler generates
a memcpy call in the Symbolizer constructor in sanitizer_symbolizer.cpp
when compiling for SPARC V8. Add HAVE_AS_SYM_ASSIGN to replace it with a
call to __sanitizer_internal_memcpy.

libsanitizer/ChangeLog:

* sanitizer_common/Makefile.am (DEFS): Add @AS_SYM_ASSIGN_DEFS@.
* sanitizer_common/Makefile.in: Regenerate.


Ok.

Jakub



We have only been granted write approval for the SPARC port. Is it
ok to push this anyway or could you help us with it?

/Daniel


[PATCH] sparc: Char arrays are 64-bit aligned on SPARC

2024-01-04 Thread Daniel Cederman
pr88077 fails on SPARC since char HeaderStr[1] in pr88077_1.c and
long HeaderStr in pr88077_0.c differs in alignment.

warning: alignment 4 of normal symbol `HeaderStr' in c_lto_pr88077_0.o is
smaller than 8 used by the common definition in c_lto_pr88077_1.o

gcc/testsuite/ChangeLog:

* gcc.dg/lto/pr88077_0.c: Change type to match alignment for SPARC
---
 gcc/testsuite/gcc.dg/lto/pr88077_0.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/lto/pr88077_0.c 
b/gcc/testsuite/gcc.dg/lto/pr88077_0.c
index 924fe9fc3f01..9455295051fc 100644
--- a/gcc/testsuite/gcc.dg/lto/pr88077_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr88077_0.c
@@ -1,3 +1,7 @@
 /* { dg-lto-do link } */
 
+#if defined __sparc__
+long long HeaderStr;
+#else
 long HeaderStr;
+#endif
-- 
2.40.1



[PATCH 1/2] sparc: Revert membar optimization that is not suitable for LEON5

2024-01-04 Thread Daniel Cederman
From: Andreas Larsson 

LEON5 has a deeper write-buffer and hence stb is not enough to flush a
write out. For compatibility, use the default V8 approach for both
LEON3 and LEON5.

This reverts commit 49cc765db35a5a21cab2aece27a44983fa70b94b,
"sync.md (*membar_storeload_leon3): New insn."

gcc/ChangeLog:

* config/sparc/sync.md (*membar_storeload_leon3): Remove
(*membar_storeload): Enable for LEON
---
 gcc/config/sparc/sync.md | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 8808ed5bc14e..ac291420b8b9 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -64,19 +64,11 @@
   "stbar"
   [(set_attr "type" "multi")])
 
-;; For LEON3, STB has the effect of membar #StoreLoad.
-(define_insn "*membar_storeload_leon3"
-  [(set (match_operand:BLK 0 "" "")
-   (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
-  "TARGET_LEON3"
-  "stb\t%%g0, [%%sp-1]"
-  [(set_attr "type" "store")])
-
 ;; For V8, LDSTUB has the effect of membar #StoreLoad.
 (define_insn "*membar_storeload"
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
-  "TARGET_V8 && !TARGET_LEON3"
+  "TARGET_V8"
   "ldstub\t[%%sp-1], %%g0"
   [(set_attr "type" "multi")])
 
-- 
2.40.1



[PATCH] sparc: Treat instructions with length 0 as empty

2024-01-04 Thread Daniel Cederman
This is to handle the membar_empty instruction that can be generated
when compiling for UT699.

gcc/ChangeLog:

* config/sparc/sparc.cc (next_active_non_empty_insn): Length 0 treated 
as empty
---
 gcc/config/sparc/sparc.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 62c57cc53159..8970674004b3 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -1119,6 +1119,7 @@ next_active_non_empty_insn (rtx_insn *insn)
   while (insn
 && (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
 || GET_CODE (PATTERN (insn)) == ASM_INPUT
+|| (get_attr_length (insn) == 0)
 || (USEFUL_INSN_P (insn)
 && (asm_noperands (PATTERN (insn)) >= 0)
 && !strcmp (decode_asm_operands (PATTERN (insn),
-- 
2.40.1



[PATCH 2/2] sparc: Add errata workaround to membar patterns

2024-01-04 Thread Daniel Cederman
LEON now uses the standard V8 membar patterns that contains an ldstub
instruction. This instruction needs to be aligned properly when the
GR712RC errata workaround is enabled.

gcc/ChangeLog:

* config/sparc/sparc.cc (atomic_insn_for_leon3_p): Treat 
membar_storeload as atomic
* config/sparc/sync.md: Add GR712RC errata workaround
---
 gcc/config/sparc/sparc.cc |  1 +
 gcc/config/sparc/sync.md  | 23 ++-
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index ebf1a557a49d..62c57cc53159 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -1052,6 +1052,7 @@ atomic_insn_for_leon3_p (rtx_insn *insn)
 {
   switch (INSN_CODE (insn))
 {
+case CODE_FOR_membar_storeload:
 case CODE_FOR_swapsi:
 case CODE_FOR_ldstub:
 case CODE_FOR_atomic_compare_and_swap_leon3_1:
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index ac291420b8b9..fa249908a55f 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -65,12 +65,19 @@
   [(set_attr "type" "multi")])
 
 ;; For V8, LDSTUB has the effect of membar #StoreLoad.
-(define_insn "*membar_storeload"
+(define_insn "membar_storeload"
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
   "TARGET_V8"
-  "ldstub\t[%%sp-1], %%g0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+return ".align\t16\n\tldstub\t[%%sp-1], %%g0";
+  else
+return "ldstub\t[%%sp-1], %%g0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+ (const_int 4) (const_int 1)))])
 
 ;; Put the two together, in combination with the fact that V8 implements PSO
 ;; as its weakest memory model, means a full barrier.  Match all remaining
@@ -80,9 +87,15 @@
(unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")]
UNSPEC_MEMBAR))]
   "TARGET_V8"
-  "stbar\n\tldstub\t[%%sp-1], %%g0"
+{
+  if (sparc_fix_gr712rc)
+return "stbar\n.align\t16\n\tldstub\t[%%sp-1], %%g0";
+  else
+return "stbar\n\tldstub\t[%%sp-1], %%g0";
+}
   [(set_attr "type" "multi")
-   (set_attr "length" "2")])
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+ (const_int 5) (const_int 2)))])
 
 ;; For V9, we have the full membar instruction.
 (define_insn "*membar"
-- 
2.40.1



[PATCH] testsuite: Skip ifcvt-4.c for SPARC V8

2024-01-08 Thread Daniel Cederman
Conditional moves are not available in SPARC V8.

gcc/testsuite/ChangeLog:

* gcc.dg/ifcvt-4.c: Skip for SPARC V8
---
 gcc/testsuite/gcc.dg/ifcvt-4.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/ifcvt-4.c b/gcc/testsuite/gcc.dg/ifcvt-4.c
index 8b2583d00e92..99ed34863bac 100644
--- a/gcc/testsuite/gcc.dg/ifcvt-4.c
+++ b/gcc/testsuite/gcc.dg/ifcvt-4.c
@@ -3,6 +3,7 @@
 /* { dg-additional-options "-march=z196" { target { s390x-*-* } } } */
 /* { dg-additional-options "-mtune-ctrl=^one_if_conv_insn" { target { i?86-*-* 
x86_64-*-* } } } */
 /* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" 
{ "arm*-*-* avr-*-* cris-*-* hppa*64*-*-* visium-*-*" riscv*-*-* msp430-*-* 
nios2-*-* pru-*-* } }  */
+/* { dg-skip-if "" { { sparc*-*-* } && { ! sparc_v9 } } }  */
 /* { dg-skip-if "" { "s390x-*-*" } { "-m31" } }  */
 
 typedef int word __attribute__((mode(word)));
-- 
2.40.1



Re: [PATCH] sparc: Char arrays are 64-bit aligned on SPARC

2024-01-08 Thread Daniel Cederman

On 2024-01-08 10:20, Eric Botcazou wrote:

pr88077 fails on SPARC since char HeaderStr[1] in pr88077_1.c and
long HeaderStr in pr88077_0.c differs in alignment.

warning: alignment 4 of normal symbol `HeaderStr' in c_lto_pr88077_0.o is
smaller than 8 used by the common definition in c_lto_pr88077_1.o


I have never seen it though.  Is that really a warning issued by GCC?



Hello Eric! Thank you for reviewing the patches!

No, this warning is not from GCC, it is from binutils ld. I forgot to 
mention that in the message. I get a similar warning from older versions 
of ld, so I do not think it is a new warning. It is also there with GCC 10.


For the OK:ed patches (with your changes), can I push them to 
release/gcc-13 in addition to master?


/Daniel


[PATCH] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-06-14 Thread Daniel Cederman
Hello all,

I'm resending this patch with an update that fixes an issue when using
it together with the -mflat flag.

-

This patch adds a workaround to the Sparc backend for the LEON3FT
store-store errata. It is enabled using the -mfix-b2bst flag.

The workaround inserts NOP instructions to prevent the following two
instruction sequences from being generated:

std -> stb/sth/st/std
stb/sth/st -> any single non-store/load instruction -> stb/sth/st/std

The __FIX_B2BST define can be used to only enable workarounds in assembly
code when the flag is used.

See GRLIB-TN-0009, "LEON3FT Stale Cache Entry After Store with Data Tag
Parity Error", for more information.

gcc/ChangeLog:

2017-01-18  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors. Enable with -mfix-b2bst.
(sparc_option_override): -mfix-ut699 implies -mfix-b2bst.
* config/sparc/sparc-c.c (sparc_target_macros): Define __FIX_B2BST.
* config/sparc/sparc.md: Prevent stores in delay slot.
* config/sparc/sparc.opt: Add -mfix-b2bst flag.
* doc/invoke.texi: Document -mfix-b2bst flag.
---
 gcc/config/sparc/sparc-c.c |   3 ++
 gcc/config/sparc/sparc.c   | 107 -
 gcc/config/sparc/sparc.md  |  10 -
 gcc/config/sparc/sparc.opt |   4 ++
 gcc/doc/invoke.texi|   7 ++-
 5 files changed, 126 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 9603173..6979f9c 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -60,4 +60,7 @@ sparc_target_macros (void)
   cpp_define (parse_in, "__VIS__=0x100");
   cpp_define (parse_in, "__VIS=0x100");
 }
+
+  if (sparc_fix_b2bst)
+builtin_define_std ("__FIX_B2BST");
 }
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 95a64a4..d5225e0 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -896,6 +896,12 @@ mem_ref (rtx x)
to properly detect the various hazards.  Therefore, this machine specific
pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)\
+  (NONDEBUG_INSN_P (INSN)  \
+   && GET_CODE (PATTERN (INSN)) != USE \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -915,6 +921,98 @@ sparc_do_work_around_errata (void)
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
  insn = seq->insn (1);
 
+  /* Look for a double-word store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8
+ && MEM_P (SET_DEST (set)))
+   {
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE(PATTERN(next)) == UNSPEC_VOLATILE) ||
+ (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (next),
+  NULL, NULL, NULL,
+  NULL, NULL), "")))
+   next = next_active_insn (next);
+ if (!next)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) == SEQUENCE)
+   continue;
+
+ if ((set = single_set (next)) == NULL_RTX)
+   continue;
+
+ /* Add NOP if double-word store is followed by any type of store.  */
+ if (MEM_P (SET_DEST (set)))
+   insert_nop = true;
+   }
+  else
+  /* Look for single-word, half-word, or byte store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) <= 4
+ && MEM_P (SET_DEST (set)))
+   {
+ rtx_insn *after;
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE(PATTERN(next)) == UNSPEC_VOLATILE) ||
+ (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (next),
+  NULL, NULL, NULL,
+  NULL, NULL), "

[PATCH] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-06-21 Thread Daniel Cederman
Hello all,

I have modified the patch so that the workaround is enabled by using
either mfix-ut699, -mfix-ut700, or -mfix-gr712rc.

Daniel

-

This patch adds a workaround to the Sparc backend for the LEON3FT
store-store errata. It is enabled when using the -mfix-ut699,
-mfix-ut700, or -mfix-gr712rc flag.

The workaround inserts NOP instructions to prevent the following two
instruction sequences from being generated:

std -> stb/sth/st/std
stb/sth/st -> any single non-store/load instruction -> stb/sth/st/std

The __FIX_B2BST define can be used to only enable workarounds in assembly
code when the flag is used.

See GRLIB-TN-0009, "LEON3FT Stale Cache Entry After Store with Data Tag
Parity Error", for more information.

gcc/ChangeLog:

2017-06-21  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors.
(sparc_option_override): -mfix-ut699, -mfix-ut700, and
-mfix-gr712rc enables the errata workaround.
* config/sparc/sparc-c.c (sparc_target_macros): Define __FIX_B2BST
when errata workaround is enabled.
* config/sparc/sparc.md: Prevent stores in delay slot.
* config/sparc/sparc.opt: Add -mfix-ut700 and -mfix-gr712rc flag.
* doc/invoke.texi: Document -mfix-ut700 and -mfix-gr712rc flag.
---
 gcc/config/sparc/sparc-c.c |   3 ++
 gcc/config/sparc/sparc.c   | 115 -
 gcc/config/sparc/sparc.md  |  10 +++-
 gcc/config/sparc/sparc.opt |  12 +
 gcc/doc/invoke.texi|  14 +-
 5 files changed, 148 insertions(+), 6 deletions(-)

diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 9603173..6979f9c 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -60,4 +60,7 @@ sparc_target_macros (void)
   cpp_define (parse_in, "__VIS__=0x100");
   cpp_define (parse_in, "__VIS=0x100");
 }
+
+  if (sparc_fix_b2bst)
+builtin_define_std ("__FIX_B2BST");
 }
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 790a036..6d6c941 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -896,6 +896,12 @@ mem_ref (rtx x)
to properly detect the various hazards.  Therefore, this machine specific
pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)\
+  (NONDEBUG_INSN_P (INSN)  \
+   && GET_CODE (PATTERN (INSN)) != USE \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -915,6 +921,98 @@ sparc_do_work_around_errata (void)
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
  insn = seq->insn (1);
 
+  /* Look for a double-word store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8
+ && MEM_P (SET_DEST (set)))
+   {
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE (PATTERN (next)) == UNSPEC_VOLATILE)
+ || (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (next),
+  NULL, NULL, NULL,
+  NULL, NULL), "")))
+   next = next_active_insn (next);
+ if (!next)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) == SEQUENCE)
+   continue;
+
+ if ((set = single_set (next)) == NULL_RTX)
+   continue;
+
+ /* Add NOP if double-word store is followed by any type of store.  */
+ if (MEM_P (SET_DEST (set)))
+   insert_nop = true;
+   }
+  else
+  /* Look for single-word, half-word, or byte store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) <= 4
+ && MEM_P (SET_DEST (set)))
+   {
+ rtx_insn *after;
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE (PATTERN (next)) == UNSPEC_VOLATILE)
+ || (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (d

Re: [PATCH] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-06-27 Thread Daniel Cederman

On 2017-06-26 09:21, Eric Botcazou wrote:


Yes, modulo the config/sparc/sparc-c.c hunk, what is it used for?



It defines __FIX_B2BST when the back-to-back store fix is enabled. This 
makes it easy to only add the workaround NOPs to inline assembly (and 
assembly files that uses the GCC preprocessor) when needed.



But the implementation looks a bit strange, can't we merge the essentially
identical blocks of code into a single block, as for the other fixes?



I will submit a new version of the patch in which I have tried to remove 
the code duplication.


--
Daniel Cederman
Cobham Gaisler


[PATCH-v3] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-06-27 Thread Daniel Cederman
This patch adds a workaround to the Sparc backend for the LEON3FT
store-store errata. It is enabled when using the -mfix-ut699,
-mfix-ut700, or -mfix-gr712rc flag.

The workaround inserts NOP instructions to prevent the following two
instruction sequences from being generated:

std -> stb/sth/st/std
stb/sth/st -> any single non-store/load instruction -> stb/sth/st/std

The __FIX_B2BST define can be used to only enable workarounds in assembly
code when the flag is used.

See GRLIB-TN-0009, "LEON3FT Stale Cache Entry After Store with Data Tag
Parity Error", for more information.

gcc/ChangeLog:

2017-06-21  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors.
(sparc_option_override): -mfix-ut699, -mfix-ut700, and
-mfix-gr712rc enables the errata workaround.
* config/sparc/sparc-c.c (sparc_target_macros): Define __FIX_B2BST
when errata workaround is enabled.
* config/sparc/sparc.md: Prevent stores in delay slot.
* config/sparc/sparc.opt: Add -mfix-ut700 and -mfix-gr712rc flag.
* doc/invoke.texi: Document -mfix-ut700 and -mfix-gr712rc flag.
---
 gcc/config/sparc/sparc-c.c |  3 ++
 gcc/config/sparc/sparc.c   | 98 +-
 gcc/config/sparc/sparc.md  | 10 -
 gcc/config/sparc/sparc.opt | 12 ++
 gcc/doc/invoke.texi| 14 ++-
 5 files changed, 131 insertions(+), 6 deletions(-)

diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 9603173..6979f9c 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -60,4 +60,7 @@ sparc_target_macros (void)
   cpp_define (parse_in, "__VIS__=0x100");
   cpp_define (parse_in, "__VIS=0x100");
 }
+
+  if (sparc_fix_b2bst)
+builtin_define_std ("__FIX_B2BST");
 }
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 790a036..ebf2eda 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -896,6 +896,12 @@ mem_ref (rtx x)
to properly detect the various hazards.  Therefore, this machine specific
pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)\
+  (NONDEBUG_INSN_P (INSN)  \
+   && GET_CODE (PATTERN (INSN)) != USE \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -915,6 +921,81 @@ sparc_do_work_around_errata (void)
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
  insn = seq->insn (1);
 
+  /* Look for either of these two sequences:
+
+Sequence A:
+1. store of word size or less (e.g. st / stb / sth / stf)
+2. any single instruction that is not a load or store
+3. any store instruction (e.g. st / stb / sth / stf / std / stdf)
+
+Sequence B:
+1. store of double word size (e.g. std / stdf)
+2. any store instruction (e.g. st / stb / sth / stf / std / stdf)  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && MEM_P (SET_DEST (set)))
+   {
+ /* Sequence B begins with a double-word store.  */
+ bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
+ rtx_insn *after;
+ int i;
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ for (after = next, i = 0; i < 2; i++)
+   {
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE (PATTERN (after)) == UNSPEC_VOLATILE)
+ || (USEFUL_INSN_P (after)
+ && (asm_noperands (PATTERN (after))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (after),
+  NULL, NULL, NULL,
+  NULL, NULL), "")))
+   after = next_active_insn (after);
+ if (!after)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (after)
+ || GET_CODE (PATTERN (after)) == SEQUENCE)
+   break;
+
+ /* Sequence B is only two instructions long.  */
+ if (seq_b)
+   {
+ /* Add NOP if followed by a store.  */
+ if ((set = single_set (after)) != NULL_RTX
+ && MEM_P (SET_DEST (set)))
+   insert_nop = true;
+
+ /* Otherwise it is ok.  */
+ break;
+

Re: [PATCH-v3] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-06-29 Thread Daniel Cederman

Hello Eric,

Thank you for reviewing the patch.


Let's forget -mfix-gr712rc for now, -mfix-ut700 is enough I think.


I think it would be confusing to use the -mfix-ut700 flag when compiling 
for the GR712RC. Now when we are not using a generic name for the errata 
workaround we should at least have unique flags for the two major CPUs 
that are afflicted by this errata.



I'm not thrilled with this, it's undocumented, the other workaround don't have
it and I don't think that we really need it.


The B2BST errata workaround requires more changes to assembler routines 
commonly used by operating systems, such as for example register window 
handling, than what the UT699 workaround needed. It would be nice to 
have a way to only enable these modification when the -mfix- flag is 
used. The alternative would be to provide a define directly on the 
compiler command line in conjunction with -mfix flag. But if more 
changes are required later on it would be good to have the define more 
closely tied to the flag to minimize the number of changes to Makefiles 
and etc.


Would it be OK to add if we document it properly?

--
Daniel Cederman
Cobham Gaisler


Re: [PATCH-v3] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-07-04 Thread Daniel Cederman



On 2017-06-30 07:11, Sebastian Huber wrote:

On 29/06/17 18:05, David Miller wrote:


From: Daniel Cederman 
Date: Thu, 29 Jun 2017 17:15:43 +0200


I'm not thrilled with this, it's undocumented, the other workaround
don't have
it and I don't think that we really need it.

The B2BST errata workaround requires more changes to assembler
routines commonly used by operating systems, such as for example
register window handling, than what the UT699 workaround needed. It
would be nice to have a way to only enable these modification when the
-mfix- flag is used. The alternative would be to provide a define
directly on the compiler command line in conjunction with -mfix
flag. But if more changes are required later on it would be good to
have the define more closely tied to the flag to minimize the number
of changes to Makefiles and etc.

Personally, I have never seen compiler based CPP defines as ever being
useful for tailoring OS assembler code.  Ever.

In most cases you will want to support several families of CPUs and
therefore sort out the individual cpu support assembler routines
internally in the kernel sources.


This depends on the operating system you use. For some  embedded systems 
where the application and the operating system are one executable it is 
quite common to use compiler provided defines in assembly code.


For example:

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/machine/arm/memcpy-armv7a.S;h=cd7962e075a30cb90ec073d77b177c3536429b9b;hb=HEAD 



For a software development kit, the run-time libraries are built for a 
set of multilibs. Each assembler file may use multilib specific compiler 
defines, e.g. floating point unit present or not, errata XYZ present or 
not, etc.




We can drop the define if necessary, but we would like to keep the two 
flags. Would that be OK to apply?


--
Daniel Cederman
Cobham Gaisler



[PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012

2017-11-20 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0012.

If the workaround is enabled it will:

* Prevent any floating-point operation from being placed in the
  delay slot of an annulled integer branch.

* Place a NOP at the branch target of an integer branch if it is
  a floating-point operation or a floating-point branch.

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (fpop_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0012 errata for
GR712RC.
(pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
* config/sparc/sparc.md (fix_gr712rc): New attribute.
(in_branch_annul_delay): Prevent floating-point instructions
in delay slot of annulled integer branch.
---
 gcc/config/sparc/sparc.c  | 50 +--
 gcc/config/sparc/sparc.md | 17 
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a9945e2..8f6eb48 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,31 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if floating-point instruction.  */
+
+static int
+fpop_insn_p (rtx_insn *insn)
+{
+  if ( GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+  switch (get_attr_type (insn))
+{
+case TYPE_FPMOVE:
+case TYPE_FPCMOVE:
+case TYPE_FP:
+case TYPE_FPCMP:
+case TYPE_FPMUL:
+case TYPE_FPDIVS:
+case TYPE_FPSQRTS:
+case TYPE_FPDIVD:
+case TYPE_FPSQRTD:
+  return true;
+default:
+  return false;
+}
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -970,11 +995,31 @@ sparc_do_work_around_errata (void)
 {
   bool insert_nop = false;
   rtx set;
+  rtx_insn *jump = 0;
 
   /* Look into the instruction in a delay slot.  */
   if (NONJUMP_INSN_P (insn))
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
- insn = seq->insn (1);
+ {
+   jump = seq->insn (0);
+   insn = seq->insn (1);
+ }
+
+  /* Place a NOP at the branch target of an integer branch if it is
+a floating-point operation or a floating-point branch.  */
+  if (sparc_fix_gr712rc
+ && (JUMP_P (insn) || jump)
+ && get_attr_branch_type (jump ? jump : insn) == BRANCH_TYPE_ICC)
+   {
+ rtx_insn *target;
+
+ target = next_active_insn (JUMP_LABEL_AS_INSN (jump ? jump : insn));
+ if (target
+ && (fpop_insn_p (target)
+ || ((JUMP_P (target)
+  && get_attr_branch_type (target) == BRANCH_TYPE_FCC
+   emit_insn_before (gen_nop (), target);
+   }
 
   /* Look for either of these two sequences:
 
@@ -1303,7 +1348,8 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
 {
-  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
+  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
+   || sparc_fix_gr712rc;
 }
 
   virtual unsigned int execute (function *)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index d9cbd4f..ef789e2 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -430,6 +430,10 @@
(symbol_ref "(sparc_fix_b2bst != 0
 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
 
+(define_attr "fix_gr712rc" "false,true"
+   (symbol_ref "(sparc_fix_gr712rc != 0
+? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
+
 ;; Length (in # of insns).
 ;; Beware that setting a length greater or equal to 3 for conditional branches
 ;; has a side-effect (see output_cbranch and output_v9branch).
@@ -590,6 +594,15 @@
   (const_string "true")
] (const_string "false")))
 
+(define_attr "in_branch_annul_delay" "false,true"
+  (cond[(and (eq_attr "fix_gr712rc" "true")
+(eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
+ fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+  (const_string "false")
+   (eq_attr "in_branch_delay" "true")
+  (const_string "true")
+   ] (const_string "false")))
+
 (define_delay (eq_attr "type" "call")
   [(eq_attr "in_call_delay" "true") (nil) (nil)])
 
@@ -602,6 +615,10 @@
 (define_delay (eq_attr "type" "branch")
   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" 
"true")])
 
+(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc"))
+  [(eq_attr "in_branch_delay" "true") (nil)
+  (eq_attr "in_branch_annul_delay" "true")])
+
 (define_delay (eq_attr "type" "uncond_branch")
   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
 
-- 
2.9.3



[PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata

2017-11-20 Thread Daniel Cederman
Hello,

This patch series adds workarounds for the newly discovered errata for UT699, 
UT700, and GR712RC. The errata and possible workarounds are described in the 
following documents available at 
http://www.gaisler.com/index.php/information/app-tech-notes:

GRLIB-TN-0010 - LEON3/FT AHB Deadlock After Sequence of Load and Atomic 
Instructions
GRLIB-TN-0011 - LEON3/FT AHB Lock Release during Atomic Operation
GRLIB-TN-0012 - GR712RC Incorrect Annulation of Floating-point Operation on 
Instruction Cache Parity Error
GRLIB-TN-0013 - GRFPU Floating-point controller: Missing FDIV/FSQRT Result

Daniel Cederman (4):
  [SPARC] Errata workaround for GRLIB-TN-0012
  [SPARC] Errata workaround for GRLIB-TN-0011
  [SPARC] Errata workaround for GRLIB-TN-0010
  [SPARC] Errata workaround for GRLIB-TN-0013

 gcc/config/sparc/sparc.c   | 205 -
 gcc/config/sparc/sparc.md  |  24 ++
 gcc/config/sparc/sparc.opt |   4 +
 gcc/config/sparc/sync.md   |  18 +++-
 4 files changed, 245 insertions(+), 6 deletions(-)

-- 
2.9.3



[PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013

2017-11-20 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0013.

If the workaround is enabled it will:

* Prevent div and sqrt instructions in the delay slot.

* Insert NOPs to prevent the sequence (div/sqrt) -> (two or three floating
  point operations or loads) -> (div/sqrt).

* Not insert NOPs if any of the floating point operations have a dependency
  on the destination register of the first (div/sqrt).

* Not insert NOPs if one of the floating point operations is a (div/sqrt).

* Insert NOPs to prevent (div/sqrt) followed by a branch.

It is applicable to GR712RC, UT700, and UT699.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (fpop_reg_depend_p): New function.
(div_sqrt_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0013 errata for
certain LEON3 processors.
(pass_work_around_errata::gate): Also test sparc_fix_tn0013.
(sparc_option_override): Set sparc_fix_tn0013 appropriately.
* config/sparc/sparc.md (fix_tn0013): New attribute.
(in_branch_delay): Prevent div and sqrt in delay slot if fix_tn0013.
* config/sparc/sparc.opt (sparc_fix_tn0013: New variable.
---
 gcc/config/sparc/sparc.c   | 114 -
 gcc/config/sparc/sparc.md  |   7 +++
 gcc/config/sparc/sparc.opt |   4 ++
 3 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 9faf774..3da642e 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,39 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if any of the floating-point instruction's source
+   registers is the same as the provided register.  */
+
+static int
+fpop_reg_depend_p (rtx_insn *insn, unsigned int reg)
+{
+  extract_insn (insn);
+  return (REGNO (recog_data.operand[1]) == reg
+ || (recog_data.n_operands == 3
+ && REGNO (recog_data.operand[2]) == reg));
+}
+
+/* True if the instruction is floating-point division or
+   floating-point square-root.  */
+
+static int
+div_sqrt_insn_p (rtx_insn *insn)
+{
+  if ( GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+  switch (get_attr_type (insn))
+{
+case TYPE_FPDIVS:
+case TYPE_FPSQRTS:
+case TYPE_FPDIVD:
+case TYPE_FPSQRTD:
+  return true;
+default:
+  return false;
+}
+}
+
 /* True if floating-point instruction.  */
 
 static int
@@ -1064,6 +1097,80 @@ sparc_do_work_around_errata (void)
insert_nop = true;
}
 
+  /* Look for sequences that could trigger the TN-0013 errata.  */
+  if (sparc_fix_tn0013
+ && NONJUMP_INSN_P (insn)
+ && div_sqrt_insn_p (insn))
+   {
+ int i;
+ int fp_found = 0;
+ unsigned int dest_reg;
+ rtx_insn *after;
+
+ dest_reg = REGNO (SET_DEST (single_set (insn)));
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ for (after = next, i = 0; i < 4; i++)
+   {
+ /* Count floating-point operations.  */
+ if (i != 3
+ && fpop_insn_p (after))
+   {
+ /* If the insn uses the destination register of
+the div/sqrt, then it cannot be problematic.  */
+ if (fpop_reg_depend_p (after, dest_reg))
+   break;
+ fp_found++;
+   }
+
+ /* Count floating-point loads.  */
+ if (i != 3
+ && (set = single_set (after)) != NULL_RTX
+ && REG_P (SET_DEST (set))
+ && REGNO (SET_DEST (set)) > 31)
+   {
+ /* If the insn uses the destination register of
+the div/sqrt, then it cannot be problematic.  */
+ if (REGNO (SET_DEST (set)) == dest_reg)
+   break;
+ fp_found++;
+   }
+
+ /* Check if this is a problematic sequence.  */
+ if (i > 1
+ && fp_found >= 2
+ && div_sqrt_insn_p (after))
+   {
+ /* Add extra NOP to prevent second version of
+problematic sequence.  */
+ if (i == 2)
+   emit_insn_before (gen_nop (), next);
+ insert_nop = true;
+ break;
+   }
+
+ /* No need to scan past a second div/sqrt.  */
+ if (div_sqrt_insn_p (after))
+   break;
+
+ /* Insert NOP before branch.  */
+ if (i < 3
+ && (!NONJUMP_INSN_P (after)
+ || GET_CODE (PATTERN (after)) == SEQUENCE))
+   {
+ insert_nop = true;
+  

[PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011

2017-11-20 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0011.

If the workaround is enabled it will:

* Insert .align 16 before atomic instructions (swap, ldstub, casa).

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
(atomic_compare_and_swap_leon3_1): Likewise.
(ldstub): Likewise.
---
 gcc/config/sparc/sync.md | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 1593bde..d5c505b 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,6 +222,8 @@
  UNSPECV_CAS))]
   "TARGET_LEON3"
 {
+  if (sparc_fix_gr712rc)
+output_asm_insn (".align\t16", operands);
   if (TARGET_SV_MODE)
 return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
   else
@@ -275,7 +277,12 @@
(set (match_dup 1)
(match_operand:SI 2 "register_operand" "0"))]
   "(TARGET_V8 || TARGET_V9) && !sparc_fix_ut699"
-  "swap\t%1, %0"
+{
+  if (sparc_fix_gr712rc)
+return ".align\t16\n\tswap\t%1, %0";
+  else
+return "swap\t%1, %0";
+}
   [(set_attr "type" "multi")])
 
 (define_expand "atomic_test_and_set"
@@ -307,5 +314,10 @@
UNSPECV_LDSTUB))
(set (match_dup 1) (const_int -1))]
   "!sparc_fix_ut699"
-  "ldstub\t%1, %0"
+{
+  if (sparc_fix_gr712rc)
+return ".align\t16\n\tldstub\t%1, %0";
+  else
+return "ldstub\t%1, %0";
+}
   [(set_attr "type" "multi")])
-- 
2.9.3



[PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010

2017-11-20 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0010.

If the workaround is enabled it will:

* Insert a NOP between load instruction and atomic
  instruction (swap, ldstub, casa).

* Insert a NOP at branch target if load in delay slot
  and atomic instruction at branch target.

It is applicable to UT700.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (atomic_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0010 errata for
UT700.
* config/sparc/sync.md (atomic_compare_and_swap_leon3_1): Make
instruction referable in atomic_insns_p.
---
 gcc/config/sparc/sparc.c | 43 +++
 gcc/config/sparc/sync.md |  2 +-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 8f6eb48..9faf774 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -970,6 +970,22 @@ fpop_insn_p (rtx_insn *insn)
 }
 }
 
+/* True if complex atomic instruction.  */
+
+static int
+atomic_insn_p (rtx_insn *insn)
+{
+  switch (INSN_CODE (insn))
+{
+case CODE_FOR_swapsi:
+case CODE_FOR_ldstub:
+case CODE_FOR_atomic_compare_and_swap_leon3_1:
+  return true;
+default:
+  return false;
+}
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -1021,6 +1037,33 @@ sparc_do_work_around_errata (void)
emit_insn_before (gen_nop (), target);
}
 
+  /* Insert a NOP between load instruction and atomic
+instruction. Insert a NOP at branch target if load
+in delay slot and atomic instruction at branch target.  */
+  if (sparc_fix_ut700
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && MEM_P (SET_SRC (set))
+ && REG_P (SET_DEST (set)))
+   {
+ if (jump)
+   {
+ rtx_insn *target;
+
+ target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+ if (target
+ && atomic_insn_p (target))
+   emit_insn_before (gen_nop (), target);
+   }
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ if (atomic_insn_p (next))
+   insert_nop = true;
+   }
+
   /* Look for either of these two sequences:
 
 Sequence A:
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index d5c505b..b1baa73 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -212,7 +212,7 @@
   "cas\t%1, %2, %0"
   [(set_attr "type" "multi")])
 
-(define_insn "*atomic_compare_and_swap_leon3_1"
+(define_insn "atomic_compare_and_swap_leon3_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "mem_noofs_operand" "+w"))
(set (match_dup 1)
-- 
2.9.3



[PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010

2017-11-27 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0010.

If the workaround is enabled it will:

* Insert a NOP between load instruction and atomic
  instruction (swap, ldstub, casa).

* Insert a NOP at branch target if load in delay slot
  and atomic instruction at branch target.

It is applicable to UT700.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (atomic_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0010 errata for
UT700.
* config/sparc/sync.md (atomic_compare_and_swap_leon3_1): Make
instruction referable in atomic_insns_p.
---
 gcc/config/sparc/sparc.c | 41 +
 gcc/config/sparc/sync.md |  2 +-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 51045db..401dfcb 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -970,6 +970,22 @@ fpop_insn_p (rtx_insn *insn)
 }
 }
 
+/* True if INSN is an atomic instruction.  */
+
+static bool
+atomic_insn_for_leon3_p (rtx_insn *insn)
+{
+  switch (INSN_CODE (insn))
+{
+case CODE_FOR_swapsi:
+case CODE_FOR_ldstub:
+case CODE_FOR_atomic_compare_and_swap_leon3_1:
+  return true;
+default:
+  return false;
+}
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -1024,6 +1040,31 @@ sparc_do_work_around_errata (void)
emit_insn_before (gen_nop (), target);
}
 
+  /* Insert a NOP between load instruction and atomic
+instruction.  Insert a NOP at branch target if load
+in delay slot and atomic instruction at branch target.  */
+  if (sparc_fix_ut700
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && MEM_P (SET_SRC (set))
+ && REG_P (SET_DEST (set)))
+   {
+ if (jump)
+   {
+ rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+ if (target
+ && atomic_insn_for_leon3_p (target))
+   emit_insn_before (gen_nop (), target);
+   }
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ if (atomic_insn_for_leon3_p (next))
+   insert_nop = true;
+   }
+
   /* Look for either of these two sequences:
 
 Sequence A:
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index ead7c77..43c66e9 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -212,7 +212,7 @@
   "cas\t%1, %2, %0"
   [(set_attr "type" "multi")])
 
-(define_insn "*atomic_compare_and_swap_leon3_1"
+(define_insn "atomic_compare_and_swap_leon3_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "mem_noofs_operand" "+w"))
(set (match_dup 1)
-- 
2.9.3



[PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013

2017-11-27 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0013.

If the workaround is enabled it will:

* Prevent div and sqrt instructions in the delay slot.

* Insert NOPs to prevent the sequence (div/sqrt) -> (two or three floating
  point operations or loads) -> (div/sqrt).

* Not insert NOPs if any of the floating point operations have a dependency
  on the destination register of the first (div/sqrt).

* Not insert NOPs if one of the floating point operations is a (div/sqrt).

* Insert NOPs to prevent (div/sqrt) followed by a branch.

It is applicable to GR712RC, UT700, and UT699.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (fpop_reg_depend_p): New function.
(div_sqrt_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0013 errata for
certain LEON3 processors.
(pass_work_around_errata::gate): Also test sparc_fix_tn0013.
(sparc_option_override): Set sparc_fix_tn0013 appropriately.
* config/sparc/sparc.md (fix_tn0013): New attribute.
(in_branch_delay): Prevent div and sqrt in delay slot if fix_tn0013.
* config/sparc/sparc.opt (sparc_fix_tn0013: New variable.
---
 gcc/config/sparc/sparc.c   | 113 -
 gcc/config/sparc/sparc.md  |   7 +++
 gcc/config/sparc/sparc.opt |   4 ++
 3 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 401dfcb..6e91114 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,39 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if any of INSN's source register(s) is REG.  */
+
+static bool
+insn_uses_reg_p (rtx_insn *insn, unsigned int reg)
+{
+  extract_insn (insn);
+  return ((REG_P (recog_data.operand[1])
+  && REGNO (recog_data.operand[1]) == reg)
+ || (recog_data.n_operands == 3
+ && REG_P (recog_data.operand[2])
+ && REGNO (recog_data.operand[2]) == reg));
+}
+
+/* True if INSN is a floating-point division or square-root.  */
+
+static bool
+div_sqrt_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+  switch (get_attr_type (insn))
+{
+case TYPE_FPDIVS:
+case TYPE_FPSQRTS:
+case TYPE_FPDIVD:
+case TYPE_FPSQRTD:
+  return true;
+default:
+  return false;
+}
+}
+
 /* True if INSN is a floating-point instruction.  */
 
 static bool
@@ -1065,6 +1098,79 @@ sparc_do_work_around_errata (void)
insert_nop = true;
}
 
+  /* Look for sequences that could trigger the GRLIB-TN-0013 errata.  */
+  if (sparc_fix_lost_divsqrt
+ && NONJUMP_INSN_P (insn)
+ && div_sqrt_insn_p (insn))
+   {
+ int i;
+ int fp_found = 0;
+ rtx_insn *after;
+
+ const unsigned int dest_reg = REGNO (SET_DEST (single_set (insn)));
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ for (after = next, i = 0; i < 4; i++)
+   {
+ /* Count floating-point operations.  */
+ if (i != 3 && fpop_insn_p (after))
+   {
+ /* If the insn uses the destination register of
+the div/sqrt, then it cannot be problematic.  */
+ if (insn_uses_reg_p (after, dest_reg))
+   break;
+ fp_found++;
+   }
+
+ /* Count floating-point loads.  */
+ if (i != 3
+ && (set = single_set (after)) != NULL_RTX
+ && REG_P (SET_DEST (set))
+ && REGNO (SET_DEST (set)) > 31)
+   {
+ /* If the insn uses the destination register of
+the div/sqrt, then it cannot be problematic.  */
+ if (REGNO (SET_DEST (set)) == dest_reg)
+   break;
+ fp_found++;
+   }
+
+ /* Check if this is a problematic sequence.  */
+ if (i > 1
+ && fp_found >= 2
+ && div_sqrt_insn_p (after))
+   {
+ /* If is this is the short version of the problematic
+sequence we add two NOPs in a row to also prevent
+the long version.  */
+ if (i == 2)
+   emit_insn_before (gen_nop (), next);
+ insert_nop = true;
+ break;
+   }
+
+ /* No need to scan past a second div/sqrt.  */
+ if (div_sqrt_insn_p (after))
+   break;
+
+ /* Insert NOP before branch.  */
+ if (i < 3
+ && (!NONJUMP_INSN_P (after)
+ 

[PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012

2017-11-27 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0012.

If the workaround is enabled it will:

* Prevent any floating-point operation from being placed in the
  delay slot of an annulled integer branch.

* Place a NOP at the branch target of an integer branch if it is
  a floating-point operation or a floating-point branch.

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (fpop_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0012 errata for
GR712RC.
(pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
* config/sparc/sparc.md (fix_gr712rc): New attribute.
(in_branch_annul_delay): Prevent floating-point instructions
in delay slot of annulled integer branch.
---
 gcc/config/sparc/sparc.c  | 57 +++
 gcc/config/sparc/sparc.md | 28 +++
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a9945e2..51045db 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,31 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if INSN is a floating-point instruction.  */
+
+static bool
+fpop_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+  switch (get_attr_type (insn))
+{
+case TYPE_FPMOVE:
+case TYPE_FPCMOVE:
+case TYPE_FP:
+case TYPE_FPCMP:
+case TYPE_FPMUL:
+case TYPE_FPDIVS:
+case TYPE_FPSQRTS:
+case TYPE_FPDIVD:
+case TYPE_FPSQRTD:
+  return true;
+default:
+  return false;
+}
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -970,11 +995,34 @@ sparc_do_work_around_errata (void)
 {
   bool insert_nop = false;
   rtx set;
+  rtx_insn *jump;
+  rtx_sequence *seq;
 
   /* Look into the instruction in a delay slot.  */
-  if (NONJUMP_INSN_P (insn))
-   if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
- insn = seq->insn (1);
+  if (NONJUMP_INSN_P (insn)
+ && (seq = dyn_cast  (PATTERN (insn
+ {
+   jump = seq->insn (0);
+   insn = seq->insn (1);
+ }
+  else if (JUMP_P (insn))
+   jump = insn;
+  else
+   jump = NULL;
+
+  /* Place a NOP at the branch target of an integer branch if it is
+a floating-point operation or a floating-point branch.  */
+  if (sparc_fix_gr712rc
+ && jump != NULL_RTX
+ && get_attr_branch_type (jump) == BRANCH_TYPE_ICC)
+   {
+ rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+ if (target
+ && (fpop_insn_p (target)
+ || ((JUMP_P (target)
+  && get_attr_branch_type (target) == BRANCH_TYPE_FCC
+   emit_insn_before (gen_nop (), target);
+   }
 
   /* Look for either of these two sequences:
 
@@ -1303,7 +1351,8 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
 {
-  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
+  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
+  || sparc_fix_gr712rc;
 }
 
   virtual unsigned int execute (function *)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index d9cbd4f..7e03bda 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -430,6 +430,10 @@
(symbol_ref "(sparc_fix_b2bst != 0
 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
 
+(define_attr "fix_gr712rc" "false,true"
+   (symbol_ref "(sparc_fix_gr712rc != 0
+? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
+
 ;; Length (in # of insns).
 ;; Beware that setting a length greater or equal to 3 for conditional branches
 ;; has a side-effect (see output_cbranch and output_v9branch).
@@ -590,6 +594,26 @@
   (const_string "true")
] (const_string "false")))
 
+(define_attr "in_integer_branch_annul_delay" "false,true"
+  (cond [(eq_attr "type" 
"uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
+  (const_string "false")
+(and (eq_attr "fix_gr712rc" "true")
+ (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
+  fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+  (const_string "false")
+(and (eq_attr "fix_b2bst" "true") (eq_attr "type" "store,fpstore"))
+  (const_string "false")
+(and (eq

[PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011

2017-11-27 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0011.

If the workaround is enabled it will:

* Insert .align 16 before atomic instructions (swap, ldstub, casa).

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
(atomic_compare_and_swap_leon3_1): Likewise.
(ldstub): Likewise.
---
 gcc/config/sparc/sync.md | 28 +++-
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 1593bde..ead7c77 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,12 +222,16 @@
  UNSPECV_CAS))]
   "TARGET_LEON3"
 {
+  if (sparc_fix_gr712rc)
+output_asm_insn (".align\t16", operands);
   if (TARGET_SV_MODE)
 return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
   else
 return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
 }
-  [(set_attr "type" "multi")])
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+ (const_int 4) (const_int 1)))])
 
 (define_insn "*atomic_compare_and_swapdi_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=h")
@@ -275,8 +279,15 @@
(set (match_dup 1)
(match_operand:SI 2 "register_operand" "0"))]
   "(TARGET_V8 || TARGET_V9) && !sparc_fix_ut699"
-  "swap\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+return ".align\t16\n\tswap\t%1, %0";
+  else
+return "swap\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+ (const_int 4) (const_int 1)))])
 
 (define_expand "atomic_test_and_set"
   [(match_operand:QI 0 "register_operand" "")
@@ -307,5 +318,12 @@
UNSPECV_LDSTUB))
(set (match_dup 1) (const_int -1))]
   "!sparc_fix_ut699"
-  "ldstub\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+return ".align\t16\n\tldstub\t%1, %0";
+  else
+return "ldstub\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+ (const_int 4) (const_int 1)))])
-- 
2.9.3



[PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata

2017-11-27 Thread Daniel Cederman
Hello Eric,

Thank you for your comments! I have updated the patches and will commit
them if you are OK with the changes.

Daniel Cederman (4):
  [SPARC] Errata workaround for GRLIB-TN-0012
  [SPARC] Errata workaround for GRLIB-TN-0011
  [SPARC] Errata workaround for GRLIB-TN-0010
  [SPARC] Errata workaround for GRLIB-TN-0013

 gcc/config/sparc/sparc.c   | 209 +++--
 gcc/config/sparc/sparc.md  |  35 
 gcc/config/sparc/sparc.opt |   4 +
 gcc/config/sparc/sync.md   |  30 +--
 4 files changed, 267 insertions(+), 11 deletions(-)

-- 
2.9.3



[PATCH 1/2] [SPARC] Prevent -mfix-ut699 from generating b2bst errata sequences

2017-11-27 Thread Daniel Cederman
The sequence
  st
  fdivd / fsqrtd
  std
was generated in some cases with -mfix-ut699 when there was
a st before the div/sqrt. This sequence could trigger the b2bst errata.

Now the following safe sequence is generated instead:
  st
  nop
  fdivd / fsqrtd
  std

gcc/ChangeLog:

2017-11-27  Martin Aberg  

* config/sparc/sparc.md (divdf3_fix): Add NOP and adjust length
to prevent b2bst errata sequence.
(sqrtdf2_fix): Likewise.
---
 gcc/config/sparc/sparc.md | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 0e45509..18d77bb 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -6221,10 +6221,10 @@ visl")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))]
   "TARGET_FPU && sparc_fix_ut699"
-  "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
+  "fdivd\t%1, %2, %0\n\tnop\n\tstd\t%0, [%%sp-8]\n\tnop"
   [(set_attr "type" "fpdivd")
(set_attr "fptype" "double")
-   (set_attr "length" "3")])
+   (set_attr "length" "4")])
 
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
@@ -6473,10 +6473,10 @@ visl")
   [(set (match_operand:DF 0 "register_operand" "=e")
(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
   "TARGET_FPU && sparc_fix_ut699"
-  "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
+  "fsqrtd\t%1, %0\n\tnop\n\tstd\t%0, [%%sp-8]\n\tnop"
   [(set_attr "type" "fpsqrtd")
(set_attr "fptype" "double")
-   (set_attr "length" "3")])
+   (set_attr "length" "4")])
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-- 
2.9.3



[PATCH 0/2] [SPARC] Fixes for UT699 errata workaround

2017-11-27 Thread Daniel Cederman
Hello,

This patch series adds two fixes for the UT699 errata workaround.

Daniel Cederman (2):
  [SPARC] Prevent -mfix-ut699 from generating b2bst errata sequences
  [SPARC] Recognize the load when accessing the GOT

 gcc/config/sparc/sparc.c  | 8 +++-
 gcc/config/sparc/sparc.md | 8 
 2 files changed, 11 insertions(+), 5 deletions(-)

-- 
2.9.3



[PATCH 2/2] [SPARC] Recognize the load when accessing the GOT

2017-11-27 Thread Daniel Cederman
Needed for the UT699 errata workaround to function correctly when
compiling with -fPIC.

gcc/ChangeLog:

2017-11-27  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Treat the
movsi_pic_gotdata_op instruction as a load for the UT699 errata
workaround.
---
 gcc/config/sparc/sparc.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 6e91114..8b11c1a 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1321,7 +1321,8 @@ sparc_do_work_around_errata (void)
   && NONJUMP_INSN_P (insn)
   && (set = single_set (insn)) != NULL_RTX
   && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) <= 4
-  && mem_ref (SET_SRC (set)) != NULL_RTX
+  && (mem_ref (SET_SRC (set)) != NULL_RTX
+  || INSN_CODE (insn) == CODE_FOR_movsi_pic_gotdata_op)
   && REG_P (SET_DEST (set))
   && REGNO (SET_DEST (set)) < 32)
{
@@ -1359,6 +1360,11 @@ sparc_do_work_around_errata (void)
   && REGNO (src) != REGNO (x)))
   && !reg_mentioned_p (x, XEXP (dest, 0)))
insert_nop = true;
+
+ /* GOT accesses uses LD.  */
+ else if (INSN_CODE (next) == CODE_FOR_movsi_pic_gotdata_op
+  && !reg_mentioned_p (x, XEXP (XEXP (src, 0), 1)))
+   insert_nop = true;
}
}
 
-- 
2.9.3



Re: [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013

2017-11-27 Thread Daniel Cederman

+(and (eq_attr "fix_lost_divsqrt" "true")
+ (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+  (const_string "false")


These lines should also be added to the in_integer_branch_annul_delay 
attribute.


/Daniel C



Re: [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012

2017-11-28 Thread Daniel Cederman

...add (and (.) (not (eq_attr "branch_type" "icc")) to the first define_delay.


Ah, OK, that makes more sense. I will submit an updated version. Thanks 
for getting back so quickly.


Daniel C



[PATCH v3 1/4] [SPARC] Errata workaround for GRLIB-TN-0012

2017-11-28 Thread Daniel Cederman
This patch provides a workaround for the errata described in GRLIB-TN-0012.

If the workaround is enabled it will:

* Prevent any floating-point operation from being placed in the
  delay slot of an annulled integer branch.

* Place a NOP at the branch target of an integer branch if it is
  a floating-point operation or a floating-point branch.

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  

* config/sparc/sparc.c (fpop_insn_p): New function.
(sparc_do_work_around_errata): Insert NOP instructions to
prevent sequences that could trigger the TN-0012 errata for
GR712RC.
(pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
* config/sparc/sparc.md (fix_gr712rc): New attribute.
(in_branch_annul_delay): Prevent floating-point instructions
in delay slot of annulled integer branch.
---
 gcc/config/sparc/sparc.c  | 57 +++
 gcc/config/sparc/sparc.md | 21 -
 2 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 83ca1dc..c656b78 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -914,6 +914,31 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if INSN is a floating-point instruction.  */
+
+static bool
+fpop_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+return false;
+
+  switch (get_attr_type (insn))
+{
+case TYPE_FPMOVE:
+case TYPE_FPCMOVE:
+case TYPE_FP:
+case TYPE_FPCMP:
+case TYPE_FPMUL:
+case TYPE_FPDIVS:
+case TYPE_FPSQRTS:
+case TYPE_FPDIVD:
+case TYPE_FPSQRTD:
+  return true;
+default:
+  return false;
+}
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
We need to have the (essentially) final form of the insn stream in order
@@ -939,11 +964,34 @@ sparc_do_work_around_errata (void)
 {
   bool insert_nop = false;
   rtx set;
+  rtx_insn *jump;
+  rtx_sequence *seq;
 
   /* Look into the instruction in a delay slot.  */
-  if (NONJUMP_INSN_P (insn))
-   if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
- insn = seq->insn (1);
+  if (NONJUMP_INSN_P (insn)
+ && (seq = dyn_cast  (PATTERN (insn
+ {
+   jump = seq->insn (0);
+   insn = seq->insn (1);
+ }
+  else if (JUMP_P (insn))
+   jump = insn;
+  else
+   jump = NULL;
+
+  /* Place a NOP at the branch target of an integer branch if it is
+a floating-point operation or a floating-point branch.  */
+  if (sparc_fix_gr712rc
+ && jump != NULL_RTX
+ && get_attr_branch_type (jump) == BRANCH_TYPE_ICC)
+   {
+ rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+ if (target
+ && (fpop_insn_p (target)
+ || ((JUMP_P (target)
+  && get_attr_branch_type (target) == BRANCH_TYPE_FCC
+   emit_insn_before (gen_nop (), target);
+   }
 
   /* Look for either of these two sequences:
 
@@ -1272,7 +1320,8 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
 {
-  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
+  return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
+ || sparc_fix_gr712rc;
 }
 
   virtual unsigned int execute (function *)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 5e1f0b7..2a83bab 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -430,6 +430,10 @@
(symbol_ref "(sparc_fix_b2bst != 0
 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
 
+(define_attr "fix_gr712rc" "false,true"
+   (symbol_ref "(sparc_fix_gr712rc != 0
+? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
+
 ;; Length (in # of insns).
 ;; Beware that setting a length greater or equal to 3 for conditional branches
 ;; has a side-effect (see output_cbranch and output_v9branch).
@@ -590,6 +594,15 @@
   (const_string "true")
] (const_string "false")))
 
+(define_attr "in_integer_branch_annul_delay" "false,true"
+  (cond [(and (eq_attr "fix_gr712rc" "true")
+ (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
+  fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+  (const_string "false")
+(eq_attr "in_branch_delay" "true")
+  (const_string "true")
+   ] (const_string "false")))
+
 (define_delay (eq_attr "type" "call")
   [(eq_attr "in_call_delay" "true") (nil) (nil)])
 
@@ -599,9 +612,15 @@
 (define_delay (eq_attr "type" "return")
   [(eq_attr 

Re: [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010

2017-12-04 Thread Daniel Cederman

Any particular reason to use MEM_P instead of mem_ref here?  It looks like
there is also a case for the b2bst workaround (only loads are concerned).


No, there was no particular reason. mem_ref seems like a better choice 
if it detects more types of loads.


/Daniel C



Re: [PATCH 1/2] [SPARC] Prevent -mfix-ut699 from generating b2bst errata sequences

2017-12-05 Thread Daniel Cederman

But isn't that the change I already rejected back in July?


You are right, that was a mistake from our side to submit it again. We 
had rediscovered the sequence using our scanning script and I forgot 
that the sequence was harmless in this case. We will update our scripts 
and revert the patch.


The person here with write access, danielh, is currently traveling, so 
we wont be able to revert it until next week. If it is urgent, could I 
ask you to revert it for us?


Thanks for checking the patches in detail and for improving the formating.

/Daniel C



[PATCH] [SPARC] Make sure that jump is to a label in errata workaround

2017-12-11 Thread Daniel Cederman
In some cases the jump could be to a return instruction and in those
cases the next_active_insn() function tries to follow an invalid pointer
which leads to a crash. This error did not manifest when using a 32-bit
version of GCC which is why I did not detect it before. Thanks to Sebastian
for reporting this to me.

gcc/ChangeLog:

2017-12-11  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Make sure
the jump is to a label.
---
 gcc/config/sparc/sparc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 00b90e5..b9c8dcc 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1032,6 +1032,7 @@ sparc_do_work_around_errata (void)
 floating-point operation or a floating-point branch.  */
   if (sparc_fix_gr712rc
  && jump
+ && jump_to_label_p (jump)
  && get_attr_branch_type (jump) == BRANCH_TYPE_ICC)
{
  rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
@@ -1051,7 +1052,7 @@ sparc_do_work_around_errata (void)
  && mem_ref (SET_SRC (set))
  && REG_P (SET_DEST (set)))
{
- if (jump)
+ if (jump && jump_to_label_p (jump))
{
  rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
  if (target && atomic_insn_for_leon3_p (target))
-- 
2.9.3



[PATCH] Generate more efficient memory barriers for LEON3

2014-06-25 Thread Daniel Cederman

Hello,

The memory barriers generated for SPARC are targeting the weakest memory 
model allowed for SPARC. The LEON3/4 SPARC processors are using a 
stronger memory model and thus have less requirements on the memory 
barriers. For LEON3/4, StoreStore is compiler-only, instead of "stbar", 
and StoreLoad can be achieved with a normal byte write "stb", instead of 
an atomic byte read-write "ldstub". The provided patch changes the 
previously mentioned memory barriers for TARGET_LEON3.


Best regards,
Daniel Cederman

ChangeLog:

2014-06-25  Daniel Cederman  

gcc/config/sparc/
* sync.md: Generate more efficient memory barriers for LEON3

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index e6e237f..26173a7 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -56,6 +56,15 @@
   [(set_attr "type" "multi")
(set_attr "length" "0")])

+;; For LEON3, membar #StoreStore is compiler-only.
+(define_insn "*membar_storestore_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (const_int 8)] UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  ""
+  [(set_attr "type" "multi")
+  (set_attr "length" "0")])
+
 ;; For V8, STBAR is exactly membar #StoreStore, by definition.
 (define_insn "*membar_storestore"
   [(set (match_operand:BLK 0 "" "")
@@ -64,6 +73,14 @@
   "stbar"
   [(set_attr "type" "multi")])

+;; For LEON3, STB has the effect of membar #StoreLoad.
+(define_insn "*membar_storeload_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  "stb\t%%g0, [%%sp-1]"
+  [(set_attr "type" "multi")])
+
 ;; For V8, LDSTUB has the effect of membar #StoreLoad.
 (define_insn "*membar_storeload"
   [(set (match_operand:BLK 0 "" "")
@@ -72,6 +89,15 @@
   "ldstub\t[%%sp-1], %%g0"
   [(set_attr "type" "multi")])

+;; For LEON3, membar #StoreLoad is enough for a full barrier.
+(define_insn "*membar_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")]
+   UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  "stb\t%%g0, [%%sp-1]"
+  [(set_attr "type" "multi")])
+
 ;; Put the two together, in combination with the fact that V8 
implements PSO

 ;; as its weakest memory model, means a full barrier.  Match all remaining
 ;; instances of the membar pattern for Sparc V8.

--
Daniel Cederman
Software Engineer
Aeroflex Gaisler AB
Aeroflex Microelectronic Solutions – HiRel
Kungsgatan 12
SE-411 19 Gothenburg, Sweden
Phone: +46 31 7758665
ceder...@gaisler.com
www.Aeroflex.com/Gaisler


[PATCH 1/2] Add mask to specify which LEON3 targets support CASA

2015-06-23 Thread Daniel Cederman
Not all LEON3 support the CASA instruction. This patch provides a mask
that can be used to specify which LEON3 targets that support CASA.

gcc/ChangeLog:

2015-06-22  Daniel Cederman  

* config/sparc/sparc.c (sparc_option_override): Mark CPU targets
  leon3 and leon3v7 as supporting the CASA instruction
* config/sparc/sparc.opt: Add mask specifying that the LEON3
  supports the CASA instruction (MASK_LEON3_CASA)
* config/sparc/sync.md: Only generate CASA for V9 and targets
  with the MASK_LEON3_CASA mask
---
 gcc/config/sparc/sparc.c   | 4 ++--
 gcc/config/sparc/sparc.opt | 3 +++
 gcc/config/sparc/sync.md   | 6 +++---
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 995a769..205e3cb 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1280,8 +1280,8 @@ sparc_option_override (void)
 { "supersparc",MASK_ISA, MASK_V8 },
 { "hypersparc",MASK_ISA, MASK_V8|MASK_FPU },
 { "leon",  MASK_ISA, MASK_V8|MASK_LEON|MASK_FPU },
-{ "leon3", MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU },
-{ "leon3v7",   MASK_ISA, MASK_LEON3|MASK_FPU },
+{ "leon3", MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU|MASK_LEON_CASA },
+{ "leon3v7",   MASK_ISA, MASK_LEON3|MASK_FPU|MASK_LEON_CASA },
 { "sparclite", MASK_ISA, MASK_SPARCLITE },
 /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
 { "f930",  MASK_ISA|MASK_FPU, MASK_SPARCLITE },
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 5c7f546..e6caa95 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -228,6 +228,9 @@ Mask(LEON)
 Mask(LEON3)
 ;; Generate code for LEON3
 
+Mask(LEON_CASA)
+;; Generate CAS instruction for LEON
+
 Mask(SPARCLITE)
 ;; Generate code for SPARClite
 
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 2fabff5..8e1baee 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -181,7 +181,7 @@
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; mod_s
(match_operand:SI 7 "const_int_operand" "")];; mod_f
-  "(TARGET_V9 || TARGET_LEON3)
+  "(TARGET_V9 || TARGET_LEON_CASA)
&& (mode != DImode || TARGET_ARCH64 || TARGET_V8PLUS)"
 {
   sparc_expand_compare_and_swap (operands);
@@ -197,7 +197,7 @@
 [(match_operand:I48MODE 2 "register_operand" "")
  (match_operand:I48MODE 3 "register_operand" "")]
 UNSPECV_CAS))])]
-  "TARGET_V9 || TARGET_LEON3"
+  "TARGET_V9 || TARGET_LEON_CASA"
   "")
 
 (define_insn "*atomic_compare_and_swap_1"
@@ -220,7 +220,7 @@
  [(match_operand:SI 2 "register_operand" "r")
   (match_operand:SI 3 "register_operand" "0")]
  UNSPECV_CAS))]
-  "TARGET_LEON3"
+  "TARGET_LEON_CASA"
 {
   if (TARGET_SV_MODE)
 return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
-- 
2.4.3



[PATCH] Make muser-mode the default for LEON3

2015-06-23 Thread Daniel Cederman
The muser-mode flag causes the CASA instruction for LEON3 to use the
user mode ASI. This is the correct behavior for almost all LEON3 targets.
For this reason it makes sense to make user mode the default. This patch
adds a flag for supervisor mode that can be used on the very few LEON3 targets
that requires CASA to use the supervisor ASI.

gcc/ChangeLog:

2015-06-22  Daniel Cederman  

* config/sparc/sparc.opt: Add supervisor mode flag (-msv-mode) and
  make user mode the default
* config/sparc/sync.md: Only use supervisor ASI for CASA when in
  supervisor mode
* doc/invoke.texi: Document msv-mode flag
---
 gcc/config/sparc/sparc.opt |  8 ++--
 gcc/config/sparc/sync.md   |  6 +++---
 gcc/doc/invoke.texi| 13 -
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 93d24a6..5c7f546 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -113,9 +113,13 @@ mrelax
 Target
 Optimize tail call instructions in assembler and linker
 
+msv-mode
+Target RejectNegative Report Mask(SV_MODE)
+Generate code that can only run in supervisor mode
+
 muser-mode
-Target Report Mask(USER_MODE)
-Do not generate code that can only run in supervisor mode
+Target RejectNegative Report InverseMask(SV_MODE)
+Do not generate code that can only run in supervisor mode (default)
 
 mcpu=
 Target RejectNegative Joined Var(sparc_cpu_and_features) 
Enum(sparc_processor_type) Init(PROCESSOR_V7)
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 7d00b10..2fabff5 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,10 +222,10 @@
  UNSPECV_CAS))]
   "TARGET_LEON3"
 {
-  if (TARGET_USER_MODE)
-return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
-  else
+  if (TARGET_SV_MODE)
 return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
+  else
+return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
 }
   [(set_attr "type" "multi")])
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b99ab1c..211e8e9 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1008,7 +1008,7 @@ See RS/6000 and PowerPC Options.
 -mhard-quad-float  -msoft-quad-float @gol
 -mstack-bias  -mno-stack-bias @gol
 -munaligned-doubles  -mno-unaligned-doubles @gol
--muser-mode  -mno-user-mode @gol
+-muser-mode  -msv-mode @gol
 -mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
 -mvis2  -mno-vis2  -mvis3  -mno-vis3 @gol
 -mcbcond -mno-cbcond @gol
@@ -21300,13 +21300,16 @@ Specifying this option avoids some rare compatibility 
problems with code
 generated by other compilers.  It is not the default because it results
 in a performance loss, especially for floating-point code.
 
+@item -msv-mode
+@opindex msv-mode
+Generate code that can only run in supervisor mode.  This is relevant
+only for the @code{casa} instruction emitted for the LEON3 processor.
+
 @item -muser-mode
-@itemx -mno-user-mode
 @opindex muser-mode
-@opindex mno-user-mode
 Do not generate code that can only run in supervisor mode.  This is relevant
-only for the @code{casa} instruction emitted for the LEON3 processor.  The
-default is @option{-mno-user-mode}.
+only for the @code{casa} instruction emitted for the LEON3 processor.  This
+is the default.
 
 @item -mno-faster-structs
 @itemx -mfaster-structs
-- 
2.4.3



[PATCH 2/2] Add leon3r0 and leon3r0v7 CPU targets

2015-06-23 Thread Daniel Cederman
Early variants of LEON3, revision 0, do not support the CASA instruction.
This patch adds two new targets, leon3r0 and leon3r0v7, that are equivalent
to leon3 and leon3v7, except that they do not support CASA.

gcc/ChangeLog:

2015-06-22  Daniel Cederman  

* config.gcc: Add leon3r0[v7] targets
* config/sparc/leon.md: Add leon3r0[v7] to FPU timing
* config/sparc/sparc-opts.h (enum processor_type): Add leon3r0[v7] 
targets
* config/sparc/sparc.c (sparc_option_override): Add leon3r0[v7] as 
targets
  without CASA support
* config/sparc/sparc.h: Add leon3r0[v7] targets
* config/sparc/sparc.md: Add leon3r0[v7] targets
* config/sparc/sparc.opt: Add leon3r0[v7] targets
* doc/invoke.texi: Add leon3r0[v7] targets
---
 gcc/config.gcc|  6 ++
 gcc/config/sparc/leon.md  | 14 +++---
 gcc/config/sparc/sparc-opts.h |  2 ++
 gcc/config/sparc/sparc.c  |  4 
 gcc/config/sparc/sparc.h  | 44 ---
 gcc/config/sparc/sparc.md |  2 ++
 gcc/config/sparc/sparc.opt|  6 ++
 gcc/doc/invoke.texi   | 22 +++---
 8 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 805638d..b10a1c9 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3322,10 +3322,7 @@ if test x$with_cpu = x ; then
  with_cpu=leon
  ;;
*-leon[3-9]*)
- with_cpu=leon3
- ;;
-   *-leon[3-9]v7*)
- with_cpu=leon3v7
+ with_cpu="`echo ${target} | sed 's/.*-\(leon[a-z0-9]*\).*$/\1/'`"
  ;;
*)
  with_cpu="`echo ${target} | sed 's/-.*$//'`"
@@ -4198,6 +4195,7 @@ case "${target}" in
"" | sparc | sparcv9 | sparc64 \
| v7 | cypress \
| v8 | supersparc | hypersparc | leon | leon3 | leon3v7 
\
+   | leon3r0 | leon3r0v7 \
| sparclite | f930 | f934 | sparclite86x \
| sparclet | tsc701 \
| v9 | ultrasparc | ultrasparc3 | niagara | niagara2 \
diff --git a/gcc/config/sparc/leon.md b/gcc/config/sparc/leon.md
index aca92fc..3441a74 100644
--- a/gcc/config/sparc/leon.md
+++ b/gcc/config/sparc/leon.md
@@ -29,11 +29,11 @@
 
 ;; Use a double reservation to work around the load pipeline hazard on UT699.
 (define_insn_reservation "leon3_load" 1
-  (and (eq_attr "cpu" "leon3,leon3v7") (eq_attr "type" "load,sload"))
+  (and (eq_attr "cpu" "leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"load,sload"))
   "leon_memory*2")
 
 (define_insn_reservation "leon_store" 2
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "store"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"store"))
   "leon_memory*2")
 
 ;; This describes Gaisler Research's FPU
@@ -44,21 +44,21 @@
 (define_cpu_unit "grfpu_ds" "grfpu")
 
 (define_insn_reservation "leon_fp_alu" 4
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "fp,fpcmp,fpmul"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"fp,fpcmp,fpmul"))
   "grfpu_alu, nothing*3")
 
 (define_insn_reservation "leon_fp_divs" 16
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "fpdivs"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"fpdivs"))
   "grfpu_ds*14, nothing*2")
 
 (define_insn_reservation "leon_fp_divd" 17
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "fpdivd"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"fpdivd"))
   "grfpu_ds*15, nothing*2")
 
 (define_insn_reservation "leon_fp_sqrts" 24
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "fpsqrts"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"fpsqrts"))
   "grfpu_ds*22, nothing*2")
 
 (define_insn_reservation "leon_fp_sqrtd" 25
-  (and (eq_attr "cpu" "leon,leon3,leon3v7") (eq_attr "type" "fpsqrtd"))
+  (and (eq_attr "cpu" "leon,leon3,leon3v7,leon3r0,leon3r0v7") (eq_attr "type" 
"fpsqrtd"))
   "grfpu_ds*23, nothing*2")
diff --git a/gcc

[PATCH] Use leon3 target for native LEON on Linux

2015-06-23 Thread Daniel Cederman
Linux requires LEON version 3 or above with CASA support.

gcc/ChangeLog:

2015-06-23  Daniel Cederman  

* config/sparc/driver-sparc.c: map /proc/cpuinfo with CPU LEON
  to leon3
---
 gcc/config/sparc/driver-sparc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/config/sparc/driver-sparc.c b/gcc/config/sparc/driver-sparc.c
index 778de2c..5969735 100644
--- a/gcc/config/sparc/driver-sparc.c
+++ b/gcc/config/sparc/driver-sparc.c
@@ -73,6 +73,7 @@ static const struct cpu_names {
   { "UltraSparc T2",   "niagara2" },
   { "UltraSparc T3",   "niagara3" },
   { "UltraSparc T4",   "niagara4" },
+  { "LEON","leon3" },
 #endif
   { NULL,  NULL }
   };
-- 
2.4.3



Re: [PATCH] Make muser-mode the default for LEON3

2015-06-23 Thread Daniel Cederman



On 2015-06-23 14:34, Jakub Jelinek wrote:

On Tue, Jun 23, 2015 at 02:22:34PM +0200, Daniel Cederman wrote:

The muser-mode flag causes the CASA instruction for LEON3 to use the
user mode ASI. This is the correct behavior for almost all LEON3 targets.
For this reason it makes sense to make user mode the default. This patch
adds a flag for supervisor mode that can be used on the very few LEON3 targets
that requires CASA to use the supervisor ASI.


Why are you adding a new option and without deprecation removing a
previously accepted (at least since 4.8) option?
For just changing the default, you really don't need to add a new option
or remove -mno-user-mode, just change the default, which can be done
e.g. by checking if the bit has been explicitly set and if not, use the
desired default, or if you want to change the Mask() name, just
make it InverseMask, but keep the options as they are.

Jakub



How does one check if the bit has been explicitly set? It was not 
obvious to me, which is why I took a similar approach to a patch I found 
for another CPU target. If it is possible to change the default without 
adding another flag then that is obviously better and I will update my 
patch.


Best regards,
Daniel Cederman



Re: [PATCH] Make muser-mode the default for LEON3

2015-06-23 Thread Daniel Cederman



On 2015-06-23 14:58, Jakub Jelinek wrote:

On Tue, Jun 23, 2015 at 02:48:45PM +0200, Daniel Cederman wrote:

How does one check if the bit has been explicitly set? It was not obvious to


if (TARGET_USER_MODE_P (target_flags_explicit))


me, which is why I took a similar approach to a patch I found for another
CPU target. If it is possible to change the default without adding another
flag then that is obviously better and I will update my patch.


Or you can just change the default target_flags, supposedly with
TargetVariable
int target_flags = MASK_USER_MODE
in the opt file, there are really many possibilities.

Jakub



Thanks! I went with your suggestion in the previous mail and removed the 
new -msv-mode option and inversed the user mode mask.


Best regards,
Daniel Cederman


[PATCH] Make muser-mode the default for LEON3

2015-06-23 Thread Daniel Cederman
The muser-mode flag causes the CASA instruction for LEON3 to use the
user mode ASI. This is the correct behavior for almost all LEON3 targets.
For this reason it makes sense to make user mode the default.

gcc/ChangeLog:

2015-06-23  Daniel Cederman  

* config/sparc/sparc.opt: Rename mask from USER_MODE to SV_MODE
  and make it inverse to change default
* config/sparc/sync.md: Only use supervisor ASI for CASA when in
  supervisor mode
* doc/invoke.texi: Document change of default
---
 gcc/config/sparc/sparc.opt | 4 ++--
 gcc/config/sparc/sync.md   | 6 +++---
 gcc/doc/invoke.texi| 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 93d24a6..85bf0bd 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -114,8 +114,8 @@ Target
 Optimize tail call instructions in assembler and linker
 
 muser-mode
-Target Report Mask(USER_MODE)
-Do not generate code that can only run in supervisor mode
+Target Report InverseMask(SV_MODE)
+Do not generate code that can only run in supervisor mode (default)
 
 mcpu=
 Target RejectNegative Joined Var(sparc_cpu_and_features) 
Enum(sparc_processor_type) Init(PROCESSOR_V7)
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 7d00b10..2fabff5 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,10 +222,10 @@
  UNSPECV_CAS))]
   "TARGET_LEON3"
 {
-  if (TARGET_USER_MODE)
-return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
-  else
+  if (TARGET_SV_MODE)
 return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
+  else
+return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
 }
   [(set_attr "type" "multi")])
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b99ab1c..86b2a73 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -21305,8 +21305,8 @@ in a performance loss, especially for floating-point 
code.
 @opindex muser-mode
 @opindex mno-user-mode
 Do not generate code that can only run in supervisor mode.  This is relevant
-only for the @code{casa} instruction emitted for the LEON3 processor.  The
-default is @option{-mno-user-mode}.
+only for the @code{casa} instruction emitted for the LEON3 processor.  This
+is the default.
 
 @item -mno-faster-structs
 @itemx -mfaster-structs
-- 
2.4.3



Re: [PATCH] Make muser-mode the default for LEON3

2015-06-26 Thread Daniel Cederman


Do they lack the CASA instruction with supervisor-mode ASI?  What happens when
the CASA instruction with user-mode ASI is executed in supervisor mode?



For all LEON3 (with CASA support) the CASA instruction works in 
supervisor-mode regardless of ASI used. In user-mode CASA only works 
with the user-mode ASI. So CASA with user-mode ASI works for both 
user-mode and supervisor-mode. By having user-mode ASI as default, one 
would not need to change flag when compiling user or kernel code.


On a few old LEON3 systems the CASA instruction only works in supervisor 
mode. Using the CASA instruction with the user-mode ASI on these systems 
is not legal and will cause a trap.


--
Daniel Cederman


Re: [PATCH 2/2] Add leon3r0 and leon3r0v7 CPU targets

2015-06-26 Thread Daniel Cederman



On 2015-06-26 09:45, Eric Botcazou wrote:

Early variants of LEON3, revision 0, do not support the CASA instruction.
This patch adds two new targets, leon3r0 and leon3r0v7, that are equivalent
to leon3 and leon3v7, except that they do not support CASA.


Why not use leon instead of leon3 for them?



The UT699 is a leon3r0 system which does not support CASA. However, to 
enable the errata fixes for UT699 with -mfix-ut699 requires the CPU 
target to be leon3. This causes the CASA instruction to be generated for 
UT699.


The instruction timing also differs between leon and leon3 and they are 
represented by different targets in binutils.


--
Daniel Cederman


Re: [PATCH 2/2] Add leon3r0 and leon3r0v7 CPU targets

2015-06-30 Thread Daniel Cederman

On 2015-06-30 11:24, Eric Botcazou wrote:

The UT699 is a leon3r0 system which does not support CASA. However, to
enable the errata fixes for UT699 with -mfix-ut699 requires the CPU
target to be leon3.


-mfix-ut699 itself is independent of the processor and doesn't require leon3.


The instruction timing also differs between leon and leon3 and they are
represented by different targets in binutils.


Yes, there is only one optimization trick for the scheduler that requires
leon3, but it doesn't affect correctness.  We could easily change that, i.e.
enable the trick for leon too if -mfix-ut699 is passed.



Thank you for the patch in your other mail that changes this!

We were also thinking of the instruction timing information found in the 
leon_costs and leon3_costs. We took a look at the values in leon_costs 
and they seem to fit well with the UT699, except for division. We got a 
bit unsure as to what leon system they are based on, as the division 
cost was wrong also for the AT697F, which is the most common leon2 
system. Would it be ok to update the division cost values of leon_costs 
so that they match UT699 and AT697F?


In general, depending on how one instantiate a leon system and which FPU 
is selected, you will get different timing. Is there a recommended way 
of adding support for this without adding additional CPU targets?
We are considering to add support for GRFPU-lite, which only differs in 
the timing.



As for binutils, they don't even know about leon3, eveything is leon for them.



Yes, that was a misunderstanding from my part.

--
Daniel Cederman


Re: [PATCH 2/2] Add leon3r0 and leon3r0v7 CPU targets

2015-07-03 Thread Daniel Cederman

One could add a -mtune-fpu switch.  Did you look at other architectures in the
GCC tree that would have similar requirements?



Thank you for the suggestion about adding a -mtune-fpu switch. I have 
not yet looked at the other architectures, but will do so before proceeding.


--
Daniel Cederman


[PATCH] save takes a single integer (register or 13-bit signed immediate)

2015-07-03 Thread Daniel Cederman
This removes a warning about operand 0 missing mode

gcc/ChangeLog:

2015-06-26  Daniel Cederman  

* config/sparc/sparc.md: Window save takes a single integer
---
 gcc/config/sparc/sparc.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index c296913..66f7306 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -6490,7 +6490,7 @@
 
 (define_insn "window_save"
   [(unspec_volatile
-   [(match_operand 0 "arith_operand" "rI")]
+   [(match_operand:SI 0 "arith_operand" "rI")]
UNSPECV_SAVEW)]
   "!TARGET_FLAT"
   "save\t%%sp, %0, %%sp"
-- 
2.4.3



[PATCH] Do not use floating point registers when compiling with -msoft-float for SPARC

2015-07-03 Thread Daniel Cederman
__builtin_apply* and __builtin_return accesses the floating point registers on
SPARC even when compiling with -msoft-float.

gcc/ChangeLog:

2015-06-26  Daniel Cederman  

* config/sparc/sparc.c (sparc_function_value_regno_p): Floating
  point registers cannot be used when compiling for a target
  without FPU.
* config/sparc/sparc.md: A function cannot return a value in a
  floating point register when compiled without floating point
  support.
---
 gcc/config/sparc/sparc.c  |  2 +-
 gcc/config/sparc/sparc.md | 26 --
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 2556eec..e0d40a5 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -7403,7 +7403,7 @@ sparc_libcall_value (machine_mode mode,
 static bool
 sparc_function_value_regno_p (const unsigned int regno)
 {
-  return (regno == 8 || regno == 32);
+  return (regno == 8 || (TARGET_FPU && regno == 32));
 }
 
 /* Do what is necessary for `va_start'.  We look at the current function
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index a561877..c296913 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -6398,7 +6398,6 @@
   ""
 {
   rtx valreg1 = gen_rtx_REG (DImode, 8);
-  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
   rtx result = operands[1];
 
   /* Pass constm1 to indicate that it may expect a structure value, but
@@ -6407,8 +6406,12 @@
 
   /* Save the function value registers.  */
   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
-  emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
- valreg2);
+  if (TARGET_FPU)
+{
+  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
+  emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 
8),
+  valreg2);
+}
 
   /* The optimizer does not know that the call sets the function value
  registers we stored in the result block.  We avoid problems by
@@ -6620,7 +6623,6 @@
   ""
 {
   rtx valreg1 = gen_rtx_REG (DImode, 24);
-  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
   rtx result = operands[0];
 
   if (! TARGET_ARCH64)
@@ -6637,14 +6639,18 @@
   emit_insn (gen_update_return (rtnreg, value));
 }
 
-  /* Reload the function value registers.  */
+  /* Reload the function value registers.
+ Put USE insns before the return.  */
   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
-  emit_move_insn (valreg2,
- adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
-
-  /* Put USE insns before the return.  */
   emit_use (valreg1);
-  emit_use (valreg2);
+
+  if ( TARGET_FPU )
+{
+  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
+  emit_move_insn (valreg2,
+  adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 
8));
+  emit_use (valreg2);
+}
 
   /* Construct the return.  */
   expand_naked_return ();
-- 
2.4.3



[PATCH] Update instruction cost for LEON

2015-07-03 Thread Daniel Cederman
gcc/ChangeLog:

2015-07-03  Daniel Cederman  

* config/sparc/sparc.c (struct processor_costs): Set div cost
for leon to match UT699 and AT697F. Set mul cost for leon3 to
match standard leon3.
---
 gcc/config/sparc/sparc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index e0d40a5..54341c5 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -251,8 +251,8 @@ struct processor_costs leon_costs = {
   COSTS_N_INSNS (5), /* imul */
   COSTS_N_INSNS (5), /* imulX */
   0, /* imul bit factor */
-  COSTS_N_INSNS (5), /* idiv */
-  COSTS_N_INSNS (5), /* idivX */
+  COSTS_N_INSNS (35), /* idiv */
+  COSTS_N_INSNS (35), /* idivX */
   COSTS_N_INSNS (1), /* movcc/movr */
   0, /* shift penalty */
 };
@@ -272,8 +272,8 @@ struct processor_costs leon3_costs = {
   COSTS_N_INSNS (15), /* fdivd */
   COSTS_N_INSNS (22), /* fsqrts */
   COSTS_N_INSNS (23), /* fsqrtd */
-  COSTS_N_INSNS (5), /* imul */
-  COSTS_N_INSNS (5), /* imulX */
+  COSTS_N_INSNS (1), /* imul */
+  COSTS_N_INSNS (1), /* imulX */
   0, /* imul bit factor */
   COSTS_N_INSNS (35), /* idiv */
   COSTS_N_INSNS (35), /* idivX */
-- 
2.4.3



Re: [PATCH] save takes a single integer (register or 13-bit signed immediate)

2015-07-07 Thread Daniel Cederman



On 2015-07-07 12:35, Eric Botcazou wrote:

2015-06-26  Daniel Cederman  

* config/sparc/sparc.md: Window save takes a single integer


This will probably break in 64-bit mode, the operand can be a DImode register.



You are right, I forgot about that. Is there a mode one can use that 
changes depending on the target architecture (32-bit on 32-bit 
architectures and 64-bit on 64-bit architectures)? Or does one have to 
add a 32-bit and a 64-bit variant of window_save?


--
Daniel Cederman


Re: [PATCH] Update instruction cost for LEON

2015-07-07 Thread Daniel Cederman

On 2015-07-07 12:37, Eric Botcazou wrote:

2015-07-03  Daniel Cederman  

* config/sparc/sparc.c (struct processor_costs): Set div cost
for leon to match UT699 and AT697F. Set mul cost for leon3 to
match standard leon3.


So UT699 is not a standard LEON3?



LEON3 exists in multiple revisions and is configurable so I agree that 
using the word standard in this context is a bit ambiguous.


I think we should delay applying this patch. First we need to look into 
how to properly provide the information on FPU selection and multiplier 
size to GCC. Otherwise we risk having to change the values again in a 
short while.


--
Daniel Cederman



Re: [PATCH] Do not use floating point registers when compiling with -msoft-float for SPARC

2015-07-07 Thread Daniel Cederman


On 2015-07-07 12:32, Eric Botcazou wrote:


ChangeLog must just describe the what, nothing more.  If the rationale is not
obvious, then a comment must be added _in the code_ itself.

* config/sparc/sparc.c (sparc_function_value_regno_p): Do not return
true on %f0 for a target without FPU.
* config/sparc/sparc.md (untyped_call): Do not save %f0 for a target
without FPU.
(untyped_return): Do not load %f0 for a target without FPU.



Understood. Thank you for looking at my patches and coming with 
improvements.


--
Daniel Cederman


[PATCH-v4] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-07-07 Thread Daniel Cederman
This patch adds a workaround to the Sparc backend for the LEON3FT
store-store errata. It is enabled when using the -mfix-ut699,
-mfix-ut700, or -mfix-gr712rc flag.

The workaround inserts NOP instructions to prevent the following two
instruction sequences from being generated:

std -> stb/sth/st/std
stb/sth/st -> any single non-store/load instruction -> stb/sth/st/std

The __FIX_B2BST define can be used to only enable workarounds in assembly
code when the flag is used.

See GRLIB-TN-0009, "LEON3FT Stale Cache Entry After Store with Data Tag
Parity Error", for more information.

gcc/ChangeLog:

2017-07-07  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors.
(sparc_option_override): -mfix-ut699, -mfix-ut700, and
-mfix-gr712rc enables the errata workaround.
* config/sparc/sparc.md: Prevent stores in delay slot.
* config/sparc/sparc.opt: Add -mfix-ut700 and -mfix-gr712rc flag.
* doc/invoke.texi: Document -mfix-ut700 and -mfix-gr712rc flag.
---
 gcc/config/sparc/sparc.c   | 98 +-
 gcc/config/sparc/sparc.md  | 10 -
 gcc/config/sparc/sparc.opt | 12 ++
 gcc/doc/invoke.texi| 14 ++-
 4 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 790a036..ebf2eda 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -896,6 +896,12 @@ mem_ref (rtx x)
to properly detect the various hazards.  Therefore, this machine specific
pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)\
+  (NONDEBUG_INSN_P (INSN)  \
+   && GET_CODE (PATTERN (INSN)) != USE \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -915,6 +921,81 @@ sparc_do_work_around_errata (void)
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
  insn = seq->insn (1);
 
+  /* Look for either of these two sequences:
+
+Sequence A:
+1. store of word size or less (e.g. st / stb / sth / stf)
+2. any single instruction that is not a load or store
+3. any store instruction (e.g. st / stb / sth / stf / std / stdf)
+
+Sequence B:
+1. store of double word size (e.g. std / stdf)
+2. any store instruction (e.g. st / stb / sth / stf / std / stdf)  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && MEM_P (SET_DEST (set)))
+   {
+ /* Sequence B begins with a double-word store.  */
+ bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
+ rtx_insn *after;
+ int i;
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ for (after = next, i = 0; i < 2; i++)
+   {
+ /* Skip empty assembly statements.  */
+ if ((GET_CODE (PATTERN (after)) == UNSPEC_VOLATILE)
+ || (USEFUL_INSN_P (after)
+ && (asm_noperands (PATTERN (after))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (after),
+  NULL, NULL, NULL,
+  NULL, NULL), "")))
+   after = next_active_insn (after);
+ if (!after)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (after)
+ || GET_CODE (PATTERN (after)) == SEQUENCE)
+   break;
+
+ /* Sequence B is only two instructions long.  */
+ if (seq_b)
+   {
+ /* Add NOP if followed by a store.  */
+ if ((set = single_set (after)) != NULL_RTX
+ && MEM_P (SET_DEST (set)))
+   insert_nop = true;
+
+ /* Otherwise it is ok.  */
+ break;
+   }
+
+ /* If the second instruction is a load or a store,
+then the sequence cannot be problematic.  */
+ if (i == 0)
+   {
+ if (((set = single_set (after)) != NULL_RTX)
+ && (MEM_P (SET_DEST (set)) || MEM_P (SET_SRC (set
+   break;
+
+ after = next_active_insn (after);
+ if (!after)
+   break;
+   }
+
+ /* Add NOP if third instruction is a store.  */
+ if (

Re: [PATCH-v3] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-07-07 Thread Daniel Cederman


On 2017-07-07 12:01, Eric Botcazou wrote:

We can drop the define if necessary, but we would like to keep the two
flags. Would that be OK to apply?


Yes, OK to apply on mainline and 7 branch with this change, thanks.



Great! Would you mind to apply the patch for us? The only person here 
with write access just went on vacation. I have submitted a new version 
(v4) with the change that applies to both main and 7.


--
Daniel Cederman
Cobham Gaisler


Re: [PATCH-v3] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-07-10 Thread Daniel Cederman



On 2017-07-07 18:04, Eric Botcazou wrote:

Great! Would you mind to apply the patch for us? The only person here
with write access just went on vacation. I have submitted a new version
(v4) with the change that applies to both main and 7.


OK, will do.



Thanks!

--
Daniel Cederman
Cobham Gaisler


Re: [PATCH-v4] [SPARC] Add a workaround for the LEON3FT store-store errata

2017-07-11 Thread Daniel Cederman

On 2017-07-11 09:21, Eric Botcazou wrote:


Applied without the undocumented tweaks to the divdf3_fix and sqrtdf2_fix
patterns.  Why are 2 nops necessary here?  The stored value doesn't matter.
And the length attribute should be adjusted if nops are added to the pattern.



The first nop was added to prevent sequence A from appearing (store -> 
fdivd -> std). But as you say, it is not needed as we do not read the 
value written by the std. The second nop was added to prevent sequence B 
(std -> store) and this one seems necessary as the value written by the 
store might be used later. OK to submit a new patch with only the second 
nop and a correct length attribute?


--
Daniel Cederman
Cobham Gaisler


[PATCH] [SPARC] Avoid b2bst errata when using -mfix-ut699

2017-07-11 Thread Daniel Cederman
The errata fix for the UT699 fdivd and fsqrtd might cause a sequence
that can trigger the b2bst errata. Adding a NOP prevents this.

gcc/ChangeLog:

2017-07-11  Daniel Cederman  

* config/sparc/sparc.md (divdf3_fix): Add NOP to prevent back
to back store errata sensitive sequence from being generated.
(sqrtdf2_fix): Likewise.
---
 gcc/config/sparc/sparc.md | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index afdc7d1..b154003 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -6171,10 +6171,10 @@ visl")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))]
   "TARGET_FPU && sparc_fix_ut699"
-  "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
+  "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
   [(set_attr "type" "fpdivd")
(set_attr "fptype" "double")
-   (set_attr "length" "2")])
+   (set_attr "length" "3")])
 
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
@@ -6423,10 +6423,10 @@ visl")
   [(set (match_operand:DF 0 "register_operand" "=e")
(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
   "TARGET_FPU && sparc_fix_ut699"
-  "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
+  "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
   [(set_attr "type" "fpsqrtd")
(set_attr "fptype" "double")
-   (set_attr "length" "2")])
+   (set_attr "length" "3")])
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-- 
2.9.3



[PATCH] [SPARC/RTEMS]: Add multilibs for LEON3FT back-to-back store workaround

2017-07-14 Thread Daniel Cederman
Replace MULTILIB_EXCEPTIONS with MULTILIB_REQUIRED for readability.
-mfix-gr712rc and -mfix-ut700 are currently equivalent.

2017-07-14  Daniel Cederman  

* config/sparc/t-rtems: Add mfix-gr712rc multilibs. Replace
MULTILIB_EXCEPTIONS with MULTILIB_REQUIRED. Match -mfix-gr712rc
with -mfix-ut700.
---
 gcc/config/sparc/t-rtems | 36 +---
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/gcc/config/sparc/t-rtems b/gcc/config/sparc/t-rtems
index 7411aaa..809840c 100644
--- a/gcc/config/sparc/t-rtems
+++ b/gcc/config/sparc/t-rtems
@@ -18,19 +18,25 @@
 #
 
 MULTILIB_OPTIONS = msoft-float mcpu=v8/mcpu=leon3/mcpu=leon3v7/mcpu=leon \
-  mfix-ut699/mfix-at697f
-MULTILIB_DIRNAMES = soft v8 leon3 leon3v7 leon ut699 at697f
-MULTILIB_MATCHES = msoft-float=mno-fpu
+  mfix-ut699/mfix-at697f/mfix-gr712rc
+MULTILIB_DIRNAMES = soft v8 leon3 leon3v7 leon ut699 at697f gr712rc
+MULTILIB_MATCHES = msoft-float=mno-fpu mfix-gr712rc=mfix-ut700
 
-MULTILIB_EXCEPTIONS = mfix-ut699
-MULTILIB_EXCEPTIONS += msoft-float/mfix-ut699
-MULTILIB_EXCEPTIONS += msoft-float/mcpu=v8/mfix-ut699
-MULTILIB_EXCEPTIONS += msoft-float/mcpu=leon3*/mfix-ut699
-MULTILIB_EXCEPTIONS += mcpu=v8/mfix-ut699
-MULTILIB_EXCEPTIONS += mcpu=leon3*/mfix-ut699
-MULTILIB_EXCEPTIONS += mfix-at697f
-MULTILIB_EXCEPTIONS += msoft-float/mfix-at697f
-MULTILIB_EXCEPTIONS += msoft-float/mcpu=v8/mfix-at697f
-MULTILIB_EXCEPTIONS += msoft-float/mcpu=leon3*/mfix-at697f
-MULTILIB_EXCEPTIONS += mcpu=v8/mfix-at697f
-MULTILIB_EXCEPTIONS += mcpu=leon3*/mfix-at697f
+MULTILIB_REQUIRED =
+MULTILIB_REQUIRED += msoft-float
+MULTILIB_REQUIRED += mcpu=v8
+MULTILIB_REQUIRED += mcpu=leon3
+MULTILIB_REQUIRED += mcpu=leon3v7
+MULTILIB_REQUIRED += mcpu=leon
+MULTILIB_REQUIRED += mcpu=leon3/mfix-gr712rc
+MULTILIB_REQUIRED += mcpu=leon3v7/mfix-gr712rc
+MULTILIB_REQUIRED += mcpu=leon/mfix-ut699
+MULTILIB_REQUIRED += mcpu=leon/mfix-at697f
+MULTILIB_REQUIRED += msoft-float/mcpu=v8
+MULTILIB_REQUIRED += msoft-float/mcpu=leon3
+MULTILIB_REQUIRED += msoft-float/mcpu=leon3v7
+MULTILIB_REQUIRED += msoft-float/mcpu=leon
+MULTILIB_REQUIRED += msoft-float/mcpu=leon3/mfix-gr712rc
+MULTILIB_REQUIRED += msoft-float/mcpu=leon3v7/mfix-gr712rc
+MULTILIB_REQUIRED += msoft-float/mcpu=leon/mfix-ut699
+MULTILIB_REQUIRED += msoft-float/mcpu=leon/mfix-at697f
-- 
2.9.3



[PATCH 1/1] sparc32: Add a workaround for the LEON3FT store-store errata

2017-01-18 Thread Daniel Cederman
Hi Eric,

This patch adds a workaround to the Sparc backend for the LEON3FT
store-store errata. It is enabled using the -mfix-b2bst flag.

The workaround inserts NOP instructions to prevent the following two
instruction sequences from being generated:

std -> stb/sth/st/std
stb/sth/st -> any single non-store/load instruction -> stb/sth/st/std

The __FIX_B2BST define can be used to only enable workarounds in assembly
code when the flag is used.

See GRLIB-TN-0009, "LEON3FT Stale Cache Entry After Store with Data Tag
Parity Error", for more information.

gcc/ChangeLog:

2017-01-18  Daniel Cederman  

* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors. Enable with -mfix-b2bst.
(sparc_option_override): -mfix-ut699 implies -mfix-b2bst.
* config/sparc/sparc-c.c (sparc_target_macros): Define __FIX_B2BST.
* config/sparc/sparc.md: Prevent stores in delay slot.
* config/sparc/sparc.opt: Add -mfix-b2bst flag.
* doc/invoke.texi: Document -mfix-b2bst flag.
---
 gcc/config/sparc/sparc-c.c |   3 ++
 gcc/config/sparc/sparc.c   | 104 -
 gcc/config/sparc/sparc.md  |  10 -
 gcc/config/sparc/sparc.opt |   4 ++
 gcc/doc/invoke.texi|   7 ++-
 5 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 9603173..6979f9c 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -60,4 +60,7 @@ sparc_target_macros (void)
   cpp_define (parse_in, "__VIS__=0x100");
   cpp_define (parse_in, "__VIS=0x100");
 }
+
+  if (sparc_fix_b2bst)
+builtin_define_std ("__FIX_B2BST");
 }
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index b9213c3..8d3d5f6 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -896,6 +896,12 @@ mem_ref (rtx x)
to properly detect the various hazards.  Therefore, this machine specific
pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)\
+  (NONDEBUG_INSN_P (INSN)  \
+   && GET_CODE (PATTERN (INSN)) != USE \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -915,6 +921,95 @@ sparc_do_work_around_errata (void)
if (rtx_sequence *seq = dyn_cast  (PATTERN (insn)))
  insn = seq->insn (1);
 
+  /* Look for a double-word store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8
+ && MEM_P (SET_DEST (set)))
+   {
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (next),
+  NULL, NULL, NULL,
+  NULL, NULL), ""))
+   next = next_active_insn (next);
+ if (!next)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) == SEQUENCE)
+   continue;
+
+ if ((set = single_set (next)) == NULL_RTX)
+   continue;
+
+ /* Add NOP if double-word store is followed by any type of store.  */
+ if (MEM_P (SET_DEST (set)))
+   insert_nop = true;
+   }
+  else
+  /* Look for single-word, half-word, or byte store.  */
+  if (sparc_fix_b2bst
+ && NONJUMP_INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && GET_MODE_SIZE (GET_MODE (SET_DEST (set))) <= 4
+ && MEM_P (SET_DEST (set)))
+   {
+ rtx_insn *after;
+
+ next = next_active_insn (insn);
+ if (!next)
+   break;
+
+ /* Skip empty assembly statements.  */
+ if (USEFUL_INSN_P (next)
+ && (asm_noperands (PATTERN (next))>=0)
+ && !strcmp (decode_asm_operands (PATTERN (next),
+  NULL, NULL, NULL,
+  NULL, NULL), ""))
+   next = next_active_insn (next);
+ if (!next)
+   break;
+
+ /* If the insn is a branch, then it cannot be problematic.  */
+ if (!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) == SEQUEN

[PATCH] libatomic: Acquire locks in increasing order to avoid deadlocks

2014-09-14 Thread Daniel Cederman
libat_lock_n acquires a set of locks from an array of locks. As done now,
locks might be acquired first from the end of the array and then from the
start of the array. Consider the scenario of two threads each trying to
acquire all locks. Thread 1 starts by taking lock 1 and thread 2 starts by
taking lock 0. Since both threads need a lock taken by the other we have
a deadlock. This patch changes the order in which locks are taken so that
it is always increasing. This way at least one thread will always make
progress.

As the cache line size is normally a power of two the div and mod operation
will be compiled to bit operations.

2014-09-14  Daniel Cederman  

* libatomic/config/posix/lock.c (libat_lock_n): Acquire
locks in increasing order to avoid deadlocks
---
 libatomic/config/posix/lock.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/libatomic/config/posix/lock.c b/libatomic/config/posix/lock.c
index a214c45..a13830f 100644
--- a/libatomic/config/posix/lock.c
+++ b/libatomic/config/posix/lock.c
@@ -81,19 +81,26 @@ libat_lock_n (void *ptr, size_t n)
 {
   uintptr_t h = addr_hash (ptr);
   size_t i = 0;
+  size_t l;
 
   /* Don't lock more than all the locks we have.  */
   if (n > PAGE_SIZE)
 n = PAGE_SIZE;
 
-  do
+  l = n / CACHLINE_SIZE + h;
+
+  if (n % CACHLINE_SIZE)
+l++;
+
+  if (l >= NLOCKS)
 {
-  pthread_mutex_lock (&locks[h].mutex);
-  if (++h == NLOCKS)
-   h = 0;
-  i += WATCH_SIZE;
+  for (i=0; i < l - NLOCKS; i++)
+pthread_mutex_lock (&locks[i].mutex);
+  l = NLOCKS;
 }
-  while (i < n);
+
+  for (i=h; i < l; i++)
+pthread_mutex_lock (&locks[i].mutex);
 }
 
 void
-- 
2.1.0



Re: [PATCH] Generate more efficient memory barriers for LEON3

2014-07-11 Thread Daniel Cederman

Hi,

Thank you for your comments.

> ..."stdbar" should never be generated since #StoreStore is implied by 
TSO.


I missed that #StoreStore is never generated for TSO, so I'm removing 
that pattern.


> OK, thanks.  Does this result in a significance performance gain?

stb seems to be at least twice as fast as ldstub.

> I think that only the membar_storeload_leon3 pattern is necessary.

The full barrier pattern membar_leon3 also gets generated so I think 
that one should be kept also.


I'm changing the pattern type to "store" and the condition on the 
original patterns to "&& !TARGET_LEON3" and resubmitting the patch.


On 2014-07-10 11:37, Eric Botcazou wrote:

The memory barriers generated for SPARC are targeting the weakest memory
model allowed for SPARC.


That's not quite true, they are targeting the sparc_memory_model, which is the
memory model selected for the architecture/OS pair by default and which can be
overridden by the user with -mmemory-model=[default|rmo|pso|tso|sc].


The LEON3/4 SPARC processors are using a stronger memory model and thus have
less requirements on the memory barriers.


My understanding is that they use TSO, in which case...


For LEON3/4, StoreStore is compiler-only, instead of "stbar",


..."stdbar" should never be generated since #StoreStore is implied by TSO.


and StoreLoad can be achieved with a normal byte write "stb", instead of
an atomic byte read-write "ldstub".


OK, thanks.  Does this result in a significance performance gain?


The provided patch changes the previously mentioned memory barriers for
TARGET_LEON3.


I think that only the membar_storeload_leon3 pattern is necessary.  Couple of
more nits: the new pattern is not "multi", it's "store" and you need to add:

   && !TARGET_LEON3

to the original membar_storeload since TARGET_LEON3 is also TARGET_V8.



--
Daniel Cederman
Software Engineer
Aeroflex Gaisler AB
Aeroflex Microelectronic Solutions – HiRel
Kungsgatan 12
SE-411 19 Gothenburg, Sweden
Phone: +46 31 7758665
ceder...@gaisler.com
www.Aeroflex.com/Gaisler


[PATCH-v2] Generate more efficient memory barriers for LEON3

2014-07-11 Thread Daniel Cederman
ChangeLog:

2014-07-11  Daniel Cederman  

gcc/config/sparc/
* sync.md: Generate more efficient memory barriers for LEON3 

---
 gcc/config/sparc/sync.md |   21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index e6e237f..05c3277 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -64,11 +64,19 @@
   "stbar"
   [(set_attr "type" "multi")])
 
+;; For LEON3, STB has the effect of membar #StoreLoad.
+(define_insn "*membar_storeload_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  "stb\t%%g0, [%%sp-1]"
+  [(set_attr "type" "store")])
+
 ;; For V8, LDSTUB has the effect of membar #StoreLoad.
 (define_insn "*membar_storeload"
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
-  "TARGET_V8"
+  "TARGET_V8 && !TARGET_LEON3"
   "ldstub\t[%%sp-1], %%g0"
   [(set_attr "type" "multi")])
 
@@ -79,7 +87,7 @@
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")]
UNSPEC_MEMBAR))]
-  "TARGET_V8"
+  "TARGET_V8 && !TARGET_LEON3"
   "stbar\n\tldstub\t[%%sp-1], %%g0"
   [(set_attr "type" "multi")
(set_attr "length" "2")])
@@ -93,6 +101,15 @@
   "membar\t%1"
   [(set_attr "type" "multi")])
 
+;; For LEON3, membar #StoreLoad is enough for a full barrier.
+(define_insn "*membar_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")]
+   UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  "stb\t%%g0, [%%sp-1]"
+  [(set_attr "type" "store")])
+
 (define_peephole2
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (match_operand:SI 1 "const_int_operand")]
-- 
1.7.9.5



Re: [PATCH] Generate more efficient memory barriers for LEON3

2014-07-11 Thread Daniel Cederman
That was an error on my side. The wrong memory model had gotten cached 
in a generated make script. Lets drop membar_leon3 also then :)


On 2014-07-11 11:15, Eric Botcazou wrote:

The full barrier pattern membar_leon3 also gets generated so I think
that one should be kept also.


Do you have a testcase?  membar is generated by sparc_emit_membar_for_model
and, for the TSO model of LEON3, implied = StoreStore | LoadLoad | LoadStore
so mm can only be StoreLoad, which means that membar_storeload will match so
the full barrier never will.



[PATCH-v3] Generate more efficient memory barriers for LEON3

2014-07-11 Thread Daniel Cederman
ChangeLog:

2014-07-11  Daniel Cederman  

gcc/config/sparc/
* sync.md: Generate more efficient memory barriers for LEON3 

---
 gcc/config/sparc/sync.md |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index e6e237f..98ac0d3 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -64,11 +64,19 @@
   "stbar"
   [(set_attr "type" "multi")])
 
+;; For LEON3, STB has the effect of membar #StoreLoad.
+(define_insn "*membar_storeload_leon3"
+  [(set (match_operand:BLK 0 "" "")
+   (unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
+  "TARGET_LEON3"
+  "stb\t%%g0, [%%sp-1]"
+  [(set_attr "type" "store")])
+
 ;; For V8, LDSTUB has the effect of membar #StoreLoad.
 (define_insn "*membar_storeload"
   [(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0) (const_int 2)] UNSPEC_MEMBAR))]
-  "TARGET_V8"
+  "TARGET_V8 && !TARGET_LEON3"
   "ldstub\t[%%sp-1], %%g0"
   [(set_attr "type" "multi")])
 
-- 
1.7.9.5



Re: [PATCH] Generate more efficient memory barriers for LEON3

2014-07-14 Thread Daniel Cederman
LEON3 has a store buffer of length 1, so an additional store is required 
to be sure that the one preceding it has been written to memory. I am 
not familiar enough with the internals of gcc to pick the optimal place 
to encode this behavior, so any suggestions from you are appreciated :)


On 2014-07-12 11:18, Eric Botcazou wrote:

That was an error on my side. The wrong memory model had gotten cached
in a generated make script. Lets drop membar_leon3 also then :)


Fine with me but, on second thoughts, if a mere "stb" is a #StoreLoad memory
barrier for LEON3, doesn't this simply mean that the memory model of the LEON3
is Strong Consistency and not TSO?  In which case, the only thing to change is
the default setting for LEON3 in sparc_option_override.



--
Daniel Cederman