aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2012-03-05 18:18:51 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2012-03-05 18:18:51 +0000
commitab6497549a266eb0a7cf74f4579e939b6a1e16b7 (patch)
tree86d563457479f906f0118fb151eff841f655de40 /gcc
parentb50530246aafbdecdea7cb69648c45523f23a787 (diff)
downloadgcc-ab6497549a266eb0a7cf74f4579e939b6a1e16b7.zip
gcc-ab6497549a266eb0a7cf74f4579e939b6a1e16b7.tar.gz
gcc-ab6497549a266eb0a7cf74f4579e939b6a1e16b7.tar.bz2
sh.h (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New hook.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/sh/sh.h6
-rw-r--r--gcc/config/sh/sh.opt4
-rw-r--r--gcc/config/sh/sync.md58
-rw-r--r--gcc/doc/invoke.texi12
5 files changed, 87 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b19d883..f101f7c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 7a2af0a..7e729478 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -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 */
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index ea87d25..37b9990 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -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
diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md
index 5e55947..113288c 100644
--- a/gcc/config/sh/sync.md
+++ b/gcc/config/sh/sync.md
@@ -404,3 +404,61 @@
"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")])
+
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 067dca8..8d69284 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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}.