Patchwork [SPARC] access to atomic compare-and-swap on LEON3

login
register
mail settings
Submitter Eric Botcazou
Date Aug. 9, 2013, 9:06 a.m.
Message ID <201308091106.17509.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/265964/
State New
Headers show

Comments

Eric Botcazou - Aug. 9, 2013, 9:06 a.m.
This enables access to the atomic compare-and-swap on LEON3 in conjunction with 
the binutils patch at:
  http://sourceware.org/ml/binutils/2013-08/msg00038.html

Tested on SPARC/Solaris and sparc-elf, applied on the mainline.


2013-08-09  Eric Botcazou  <ebotcazou@adacore.com>

	* configure.ac: Add GAS check for LEON instructions on SPARC.
	* configure: Regenerate.
	* config.in: Likewise.
	* config.gcc (with_cpu): Remove sparc-leon*-* and deal with LEON in the
	sparc*-*-* block.
	* config/sparc/sparc.opt (LEON, LEON3): New masks.
	* config/sparc/sparc.h (ASM_CPU32_DEFAULT_SPEC): Set to AS_LEON_FLAG
	for LEON or LEON3.
	(ASM_CPU_SPEC): Pass AS_LEON_FLAG if -mcpu=leon or -mcpu=leon3.
	(AS_LEON_FLAG): New macro.
	* config/sparc/sparc.c (sparc_option_override): Set MASK_LEON for leon
	and MASK_LEON3 for leon3 and unset them if HAVE_AS_LEON is not defined.
	Deal with LEON and LEON3 for the memory model.
	* config/sparc/sync.m (atomic_compare_and_swap<mode>): Enable for LEON3
	(atomic_compare_and_swap<mode>_1): Likewise.
	(*atomic_compare_and_swap<mode>_1): Likewise.
Deng Hengyi - Aug. 9, 2013, 4:03 p.m.
Hi Eric,

Thank you very much for your work. I will test it ASAP

WeiY
Best Regards
在 2013-8-9,下午5:06,Eric Botcazou <ebotcazou@adacore.com> 写道:

> This enables access to the atomic compare-and-swap on LEON3 in conjunction with 
> the binutils patch at:
>  http://sourceware.org/ml/binutils/2013-08/msg00038.html
> 
> Tested on SPARC/Solaris and sparc-elf, applied on the mainline.
> 
> 
> 2013-08-09  Eric Botcazou  <ebotcazou@adacore.com>
> 
> 	* configure.ac: Add GAS check for LEON instructions on SPARC.
> 	* configure: Regenerate.
> 	* config.in: Likewise.
> 	* config.gcc (with_cpu): Remove sparc-leon*-* and deal with LEON in the
> 	sparc*-*-* block.
> 	* config/sparc/sparc.opt (LEON, LEON3): New masks.
> 	* config/sparc/sparc.h (ASM_CPU32_DEFAULT_SPEC): Set to AS_LEON_FLAG
> 	for LEON or LEON3.
> 	(ASM_CPU_SPEC): Pass AS_LEON_FLAG if -mcpu=leon or -mcpu=leon3.
> 	(AS_LEON_FLAG): New macro.
> 	* config/sparc/sparc.c (sparc_option_override): Set MASK_LEON for leon
> 	and MASK_LEON3 for leon3 and unset them if HAVE_AS_LEON is not defined.
> 	Deal with LEON and LEON3 for the memory model.
> 	* config/sparc/sync.m (atomic_compare_and_swap<mode>): Enable for LEON3
> 	(atomic_compare_and_swap<mode>_1): Likewise.
> 	(*atomic_compare_and_swap<mode>_1): Likewise.
> 
> 
> -- 
> Eric Botcazou
> <p.diff>

Patch

Index: configure.ac
===================================================================
--- configure.ac	(revision 201177)
+++ configure.ac	(working copy)
@@ -3613,6 +3613,19 @@  foo:
        kasumi_fi_xor %f46, %f48, %f50, %f52],,
       [AC_DEFINE(HAVE_AS_SPARC4, 1,
                 [Define if your assembler supports SPARC4 instructions.])])
+
+    gcc_GAS_CHECK_FEATURE([LEON instructions],
+      gcc_cv_as_sparc_leon,,
+      [-Aleon],
+      [.text
+       .register %g2, #scratch
+       .register %g3, #scratch
+       .align 4
+       smac %g2, %g3, %g1
+       umac %g2, %g3, %g1
+       cas [[%g2]], %g3, %g1],,
+      [AC_DEFINE(HAVE_AS_LEON, 1,
+                [Define if your assembler supports LEON instructions.])])
     ;;
 
 changequote(,)dnl
Index: config.gcc
===================================================================
--- config.gcc	(revision 201177)
+++ config.gcc	(working copy)
@@ -3041,11 +3041,18 @@  if test x$with_cpu = x ; then
          with_cpu=8540
       fi       
       ;;
-    sparc-leon*-*)
-      with_cpu=v8;
-      ;;
     sparc*-*-*)
-      with_cpu="`echo ${target} | sed 's/-.*$//'`"
+      case ${target} in
+	*-leon-*)
+	  with_cpu=leon
+	  ;;
+	*-leon[3-9]*)
+	  with_cpu=leon3
+	  ;;
+	*)
+	  with_cpu="`echo ${target} | sed 's/-.*$//'`"
+	  ;;
+      esac
       ;;
   esac
 
Index: config/sparc/sparc.opt
===================================================================
--- config/sparc/sparc.opt	(revision 201177)
+++ config/sparc/sparc.opt	(working copy)
@@ -211,6 +211,12 @@  Enable workarounds for the errata of the
 Mask(LONG_DOUBLE_128)
 ;; Use 128-bit long double
 
+Mask(LEON)
+;; Generate code for LEON
+
+Mask(LEON3)
+;; Generate code for LEON3
+
 Mask(SPARCLITE)
 ;; Generate code for SPARClite
 
Index: config/sparc/sync.md
===================================================================
--- config/sparc/sync.md	(revision 201177)
+++ config/sparc/sync.md	(working copy)
@@ -161,7 +161,8 @@  (define_expand "atomic_compare_and_swap<
    (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 && (<MODE>mode != DImode || TARGET_ARCH64 || TARGET_V8PLUS)"
+  "(TARGET_V9 || TARGET_LEON3)
+   && (<MODE>mode != DImode || TARGET_ARCH64 || TARGET_V8PLUS)"
 {
   sparc_expand_compare_and_swap (operands);
   DONE;
@@ -176,7 +177,7 @@  (define_expand "atomic_compare_and_swap<
 	     [(match_operand:I48MODE 2 "register_operand" "")
 	      (match_operand:I48MODE 3 "register_operand" "")]
 	     UNSPECV_CAS))])]
-  "TARGET_V9"
+  "TARGET_V9 || TARGET_LEON3"
   "")
 
 (define_insn "*atomic_compare_and_swap<mode>_1"
@@ -187,7 +188,7 @@  (define_insn "*atomic_compare_and_swap<m
 	  [(match_operand:I48MODE 2 "register_operand" "r")
 	   (match_operand:I48MODE 3 "register_operand" "0")]
 	  UNSPECV_CAS))]
-  "TARGET_V9 && (<MODE>mode == SImode || TARGET_ARCH64)"
+  "(TARGET_V9 || TARGET_LEON3) && (<MODE>mode != DImode || TARGET_ARCH64)"
   "cas<modesuffix>\t%1, %2, %0"
   [(set_attr "type" "multi")])
 
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 201466)
+++ config/sparc/sparc.c	(working copy)
@@ -1140,9 +1140,8 @@  sparc_option_override (void)
     /* TI TMS390Z55 supersparc */
     { "supersparc",	MASK_ISA, MASK_V8 },
     { "hypersparc",	MASK_ISA, MASK_V8|MASK_FPU },
-    /* LEON */
-    { "leon",		MASK_ISA, MASK_V8|MASK_FPU },
-    { "leon3",		MASK_ISA, MASK_V8|MASK_FPU },
+    { "leon",		MASK_ISA, MASK_V8|MASK_LEON|MASK_FPU },
+    { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU },
     { "sparclite",	MASK_ISA, MASK_SPARCLITE },
     /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
     { "f930",		MASK_ISA|MASK_FPU, MASK_SPARCLITE },
@@ -1302,6 +1301,9 @@  sparc_option_override (void)
 #ifndef HAVE_AS_SPARC4
 		   & ~MASK_CBCOND
 #endif
+#ifndef HAVE_AS_LEON
+		   & ~(MASK_LEON | MASK_LEON3)
+#endif
 		   );
 
   /* If -mfpu or -mno-fpu was explicitly used, don't override with
@@ -1430,6 +1432,10 @@  sparc_option_override (void)
       /* Choose the most relaxed model for the processor.  */
       else if (TARGET_V9)
 	sparc_memory_model = SMM_RMO;
+      else if (TARGET_LEON3)
+	sparc_memory_model = SMM_TSO;
+      else if (TARGET_LEON)
+	sparc_memory_model = SMM_SC;
       else if (TARGET_V8)
 	sparc_memory_model = SMM_PSO;
       else
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 201177)
+++ config/sparc/sparc.h	(working copy)
@@ -236,7 +236,7 @@  extern enum cmodel sparc_cmodel;
 #if TARGET_CPU_DEFAULT == TARGET_CPU_leon \
  || TARGET_CPU_DEFAULT == TARGET_CPU_leon3
 #define CPP_CPU32_DEFAULT_SPEC "-D__leon__ -D__sparc_v8__"
-#define ASM_CPU32_DEFAULT_SPEC ""
+#define ASM_CPU32_DEFAULT_SPEC AS_LEON_FLAG
 #endif
 
 #endif
@@ -332,8 +332,8 @@  extern enum cmodel sparc_cmodel;
 %{mcpu=v8:-Av8} \
 %{mcpu=supersparc:-Av8} \
 %{mcpu=hypersparc:-Av8} \
-%{mcpu=leon:-Av8} \
-%{mcpu=leon3:-Av8} \
+%{mcpu=leon:" AS_LEON_FLAG "} \
+%{mcpu=leon3:" AS_LEON_FLAG "} \
 %{mv8plus:-Av8plus} \
 %{mcpu=v9:-Av9} \
 %{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
@@ -1758,6 +1758,12 @@  extern int sparc_indent_opcode;
 #define AS_NIAGARA4_FLAG "-Av9" AS_NIAGARA3_FLAG
 #endif
 
+#ifdef HAVE_AS_LEON
+#define AS_LEON_FLAG "-Aleon"
+#else
+#define AS_LEON_FLAG "-Av8"
+#endif
+
 /* We use gcc _mcount for profiling.  */
 #define NO_PROFILE_COUNTERS 0