@@ -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
@@ -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)));
}
@@ -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)