diff mbox

[5/5] sparc: Add -mmmodel command-line option.

Message ID 1321562265-12743-6-git-send-email-rth@redhat.com
State New
Headers show

Commit Message

Richard Henderson Nov. 17, 2011, 8:37 p.m. UTC
---
 gcc/config/sparc/sparc-opts.h |   10 ++++++++
 gcc/config/sparc/sparc.c      |   48 ++++++++++++++++++++++++++++++++++++++++-
 gcc/config/sparc/sparc.opt    |   22 ++++++++++++++++++
 3 files changed, 79 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/gcc/config/sparc/sparc-opts.h b/gcc/config/sparc/sparc-opts.h
index 266cb14..34a1955 100644
--- a/gcc/config/sparc/sparc-opts.h
+++ b/gcc/config/sparc/sparc-opts.h
@@ -47,4 +47,14 @@  enum processor_type {
   PROCESSOR_NATIVE
 };
 
+/* Sparc system memory model.  See Appendix D in the SparcV9 manual
+   for formal specification, and Appendix J for more discussion.  */
+enum memory_order {
+  MO_DEFAULT,	/* Uninitialized.  */
+  MO_RMO,	/* Relaxed Memory Order.  */
+  MO_PSO,	/* Partial Store Order.  */
+  MO_TSO,	/* Total Store Order.  */
+  MO_SC		/* Sequential Consistency.  */
+};
+
 #endif
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d75fc1a..788063d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1160,6 +1160,17 @@  sparc_option_override (void)
       gcc_unreachable ();
     };
 
+  if (sparc_memory_order == MO_DEFAULT)
+    {
+      /* Choose the most relaxed model for the processor.  */
+      if (TARGET_V9)
+	sparc_memory_order = MO_RMO;
+      else if (TARGET_V8)
+	sparc_memory_order = MO_PSO;
+      else
+	sparc_memory_order = MO_SC;
+    }
+
 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
   if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
     target_flags |= MASK_LONG_DOUBLE_128;
@@ -10863,7 +10874,39 @@  sparc_emit_membar_for_model (enum memmodel model,
   const int LoadStore = 4;
   const int StoreStore = 8;
 
-  int mm = 0;
+  int mm = 0, implied = 0;
+
+  switch (sparc_memory_order)
+    {
+    case MO_SC:
+      /* Sequential Consistency.  All memory transactions are immediately
+	 visible in sequential execution order.  No barriers needed.  */
+      return;
+
+    case MO_TSO:
+      /* Total Store Ordering: all memory transactions with store semantics
+	 are followed by an implied StoreStore.  */
+      implied |= StoreStore;
+      /* FALLTHRU */
+
+    case MO_PSO:
+      /* Partial Store Ordering: all memory transactions with load semantics
+	 are followed by an implied LoadLoad | LoadStore.  */
+      implied |= LoadLoad | LoadStore;
+
+      /* If we're not looking for a raw barrer (before+after), then atomic
+	 operations get the benefit of being both load and store.  */
+      if (load_store == 3 && before_after == 2)
+	implied |= StoreLoad | StoreStore;
+      /* FALLTHRU */
+
+    case MO_RMO:
+      /* Relaxed Memory Ordering: no implicit bits.  */
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
 
   if (before_after & 1)
     {
@@ -10890,6 +10933,9 @@  sparc_emit_membar_for_model (enum memmodel model,
 	}
     }
 
+  /* Remove the bits implied by the system memory model.  */
+  mm &= ~implied;
+
   if (mm)
     emit_insn (gen_membar (GEN_INT (mm)));
 }
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index cb807fd..e913612 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -215,3 +215,25 @@  Mask(V9)
 Mask(DEPRECATED_V8_INSNS)
 ;; Generate code that uses the V8 instructions deprecated
 ;; in the V9 architecture.
+
+mmmodel=
+Target RejectNegative Joined Var(sparc_memory_order) Enum(sparc_memory_order) Init(MO_DEFAULT)
+Specify the memory model in effect for the program.
+
+Enum
+Name(sparc_memory_order) Type(enum memory_order)
+
+EnumValue
+Enum(sparc_memory_order) String(default) Value(MO_DEFAULT)
+
+EnumValue
+Enum(sparc_memory_order) String(rmo) Value(MO_RMO)
+
+EnumValue
+Enum(sparc_memory_order) String(pso) Value(MO_PSO)
+
+EnumValue
+Enum(sparc_memory_order) String(tso) Value(MO_TSO)
+
+EnumValue
+Enum(sparc_memory_order) String(sc) Value(MO_SC)