sh.h (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New hook.
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 5 Mar 2012 18:18:51 +0000 (18:18 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 5 Mar 2012 18:18:51 +0000 (18:18 +0000)
* config/sh/sh.h (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New hook.
* config/sh/sync.md (atomic_test_and_set): New expander.
(tasb, atomic_test_and_set_soft): New insns.
* config/sh/sh.opt (menable-tas): New option.
* doc/invoke.texi (SH Options): Document it.

From-SVN: r184947

gcc/ChangeLog
gcc/config/sh/sh.h
gcc/config/sh/sh.opt
gcc/config/sh/sync.md
gcc/doc/invoke.texi

index b19d8834a741afd41e7b3f157771b057c113e591..f101f7cf1e91da90a19e600d81dc756fcf263180 100644 (file)
@@ -1,3 +1,11 @@
+2012-03-05  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       * config/sh/sh.h (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New hook.
+       * config/sh/sync.md (atomic_test_and_set): New expander.
+       (tasb, atomic_test_and_set_soft): New insns.
+       * config/sh/sh.opt (menable-tas): New option.
+       * doc/invoke.texi (SH Options): Document it.
+
 2012-03-05  Richard Guenther  <rguenther@suse.de>
 
        * cfgloop.c (verify_loop_structure): Verify dominators before
index 7a2af0a2841b3fa9a04d4ce44a381f18fc62545b..7e729478a505f363af3d5f69b0b1f80d5c2849ce 100644 (file)
@@ -2473,4 +2473,10 @@ extern int current_function_interrupt;
 /* FIXME: middle-end support for highpart optimizations is missing.  */
 #define high_life_started reload_in_progress
 
+/* The tas.b instruction sets the 7th bit in the byte, i.e. 0x80.
+   This value is used by optabs.c atomic op expansion code as well as in 
+   sync.md.  */
+#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
+#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 0x80
+
 #endif /* ! GCC_SH_H */
index ea87d259f396d05ca18ab69d61aa174679a65190..37b99904a0b2470a7e590a1938d6ad545e0473b1 100644 (file)
@@ -323,6 +323,10 @@ msoft-atomic
 Target Report Mask(SOFT_ATOMIC)
 Use software atomic sequences supported by kernel
 
+menable-tas
+Target Report RejectNegative Var(TARGET_ENABLE_TAS)
+Use tas.b instruction for __atomic_test_and_set
+
 mspace
 Target RejectNegative Alias(Os)
 Deprecated.  Use -Os instead
index 5e55947b66b8040d1aa743cca6c647b8382b2ab9..113288c7629530174e28ff6c2e3cdec954040759 100644 (file)
         "1:    mov     r1,r15";
 }
   [(set_attr "length" "18")])
+
+(define_expand "atomic_test_and_set"
+  [(match_operand:SI 0 "register_operand" "")          ;; bool result output
+   (match_operand:QI 1 "memory_operand" "")            ;; memory
+   (match_operand:SI 2 "const_int_operand" "")]                ;; model
+  "(TARGET_SOFT_ATOMIC || TARGET_ENABLE_TAS) && !TARGET_SHMEDIA"
+{
+  rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
+
+  if (TARGET_ENABLE_TAS)
+    emit_insn (gen_tasb (addr));
+  else
+    {
+      rtx val = force_reg (QImode, 
+                          gen_int_mode (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL,
+                                        QImode));
+      emit_insn (gen_atomic_test_and_set_soft (addr, val));
+    }
+
+  /* The result of the test op is the inverse of what we are
+     supposed to return.  Thus invert the T bit.  The inversion will be
+     potentially optimized away and integrated into surrounding code.  */
+  emit_insn (gen_movnegt (operands[0]));
+  DONE;
+})
+
+(define_insn "tasb"
+  [(set (reg:SI T_REG)
+       (eq:SI (mem:QI (match_operand:SI 0 "register_operand" "r"))
+              (const_int 0)))
+   (set (mem:QI (match_dup 0))
+       (unspec:QI [(const_int 128)] UNSPEC_ATOMIC))]
+  "TARGET_ENABLE_TAS && !TARGET_SHMEDIA"
+  "tas.b       @%0"
+  [(set_attr "insn_class" "co_group")])
+
+(define_insn "atomic_test_and_set_soft"
+  [(set (reg:SI T_REG)
+       (eq:SI (mem:QI (match_operand:SI 0 "register_operand" "u"))
+              (const_int 0)))
+   (set (mem:QI (match_dup 0))
+       (unspec:QI [(match_operand:QI 1 "register_operand" "u")] UNSPEC_ATOMIC))
+   (clobber (match_scratch:QI 2 "=&u"))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_SOFT_ATOMIC && !TARGET_ENABLE_TAS && !TARGET_SHMEDIA"
+{
+  return "mova 1f,r0"                  "\n"
+        "      .align 2"               "\n"
+        "      mov     r15,r1"         "\n"
+        "      mov     #(0f-1f),r15"   "\n"
+        "0:    mov.b   @%0,%2"         "\n"
+        "      mov.b   %1,@%0"         "\n"
+        "1:    mov     r1,r15"         "\n"
+        "      tst     %2,%2";
+}
+  [(set_attr "length" "16")])
+
index 067dca8e1562d82034823eff245cac14114b71f5..8d6928426d3b65fab45272812a7c7f4f7640891e 100644 (file)
@@ -887,7 +887,8 @@ See RS/6000 and PowerPC Options.
 -mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
 -maccumulate-outgoing-args -minvalid-symbols -msoft-atomic @gol
--mbranch-cost=@var{num} -mcbranchdi -mcmpeqdi -mfused-madd -mpretend-cmove}
+-mbranch-cost=@var{num} -mcbranchdi -mcmpeqdi -mfused-madd -mpretend-cmove @gol
+-menable-tas}
 
 @emph{Solaris 2 Options}
 @gccoptlist{-mimpure-text  -mno-impure-text @gol
@@ -17934,6 +17935,15 @@ single-core systems.  They will not perform correctly on multi-core systems.
 This option is enabled by default when the target is @code{sh-*-linux*}.
 For details on the atomic built-in functions see @ref{__atomic Builtins}.
 
+@item -menable-tas
+@opindex menable-tas
+Generate the @code{tas.b} opcode for @code{__atomic_test_and_set}.
+Notice that depending on the particular hardware and software configuration
+this can degrade overall performance due to the operand cache line flushes
+that are implied by the @code{tas.b} instruction.  On multi-core SH4A
+processors the @code{tas.b} instruction must be used with caution since it
+can result in data corruption for certain cache configurations.
+
 @item -mspace
 @opindex mspace
 Optimize for space instead of speed.  Implied by @option{-Os}.