Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-05 Thread Richard Henderson
On 03/04/2012 11:09 AM, Oleg Endo wrote:
 Richard, could you also please take the
 TARGET_ATOMIC_TEST_AND_SET_TRUEVAL hunk from this patch for the 4.7
 branch?

Done.  I've also moved the TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 
definition from sh.h to sh.c where it belongs.


r~


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-05 Thread Oleg Endo
On Mon, 2012-03-05 at 11:00 -0800, Richard Henderson wrote:
 On 03/04/2012 11:09 AM, Oleg Endo wrote:
  Richard, could you also please take the
  TARGET_ATOMIC_TEST_AND_SET_TRUEVAL hunk from this patch for the 4.7
  branch?
 
 Done.  

Thanks!

 I've also moved the TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 
 definition from sh.h to sh.c where it belongs.

Yeah, however, I'm also using the value behind
TARGET_ATOMIC_TEST_AND_SET_TRUEVAL in sync.md.  If it's in sh.c it
doesn't work.  That's why I left it in sh.h.

Cheers,
Oleg



Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-05 Thread Richard Henderson
On 03/05/2012 01:44 PM, Oleg Endo wrote:
 Yeah, however, I'm also using the value behind
 TARGET_ATOMIC_TEST_AND_SET_TRUEVAL in sync.md.  If it's in sh.c it
 doesn't work.  That's why I left it in sh.h.

That value should be available via targetm.atomic_test_and_set_trueval.


r~


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-05 Thread Richard Henderson
On 03/05/2012 01:49 PM, Richard Henderson wrote:
 On 03/05/2012 01:44 PM, Oleg Endo wrote:
 Yeah, however, I'm also using the value behind
 TARGET_ATOMIC_TEST_AND_SET_TRUEVAL in sync.md.  If it's in sh.c it
 doesn't work.  That's why I left it in sh.h.
 
 That value should be available via targetm.atomic_test_and_set_trueval.

Fixed thus.


r~
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9a35295..0b7e635 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3495,8 +3495,8 @@ insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) 
coretypes.h \
 insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)  \
   $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H)   \
   dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H)\
-  $(RESOURCE_H) reload.h $(DIAGNOSTIC_CORE_H) $(REGS_H) tm-constrs.h $(GGC_H)  
\
-  $(BASIC_BLOCK_H) $(INTEGRATE_H)
+  $(RESOURCE_H) reload.h $(DIAGNOSTIC_CORE_H) $(REGS_H) tm-constrs.h   \
+  $(GGC_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) $(TARGET_H)
 insn-enums.o : insn-enums.c $(CONFIG_H) $(SYSTEM_H) insn-constants.h
 insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h\
   $(TM_H) $(RTL_H) $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H)
diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md
index 113288c..258e048 100644
--- a/gcc/config/sh/sync.md
+++ b/gcc/config/sh/sync.md
@@ -417,9 +417,10 @@
 emit_insn (gen_tasb (addr));
   else
 {
-  rtx val = force_reg (QImode, 
-  gen_int_mode (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL,
-QImode));
+  rtx val;
+
+  val = gen_int_mode (targetm.atomic_test_and_set_trueval, QImode);
+  val = force_reg (QImode, val);
   emit_insn (gen_atomic_test_and_set_soft (addr, val));
 }
 
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 662d8ca..173e4d3 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -812,7 +812,8 @@ from the machine description file `md'.  */\n\n);
   printf (#include \tm-constrs.h\\n);
   printf (#include \ggc.h\\n);
   printf (#include \basic-block.h\\n);
-  printf (#include \integrate.h\\n\n);
+  printf (#include \integrate.h\\n);
+  printf (#include \target.h\\n\n);
   printf (#define FAIL return (end_sequence (), _val)\n);
   printf (#define DONE return (_val = get_insns (), end_sequence (), 
_val)\n\n);
 


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-04 Thread Oleg Endo
On Sat, 2012-03-03 at 10:31 -0800, Richard Henderson wrote:
 On 03/02/2012 10:11 AM, Richard Henderson wrote:
  I'm in the process of sanity testing this on x86_64 with trueval set to 
  0x80.
  Jakub, ok for 4.7 branch if it passes?
  
  * optabs.c (expand_atomic_test_and_set): Honor
  atomic_test_and_set_trueval even when atomic_test_and_set
  optab is not in use.
 
 I've committed this patch to mainline.  I still think it ought to 
 go onto the 4.7 branch...
 

Attached is a slightly modified version of the patch from
http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00085.html

I have removed the signed char weirdo and adjusted the comment above
TARGET_ATOMIC_TEST_AND_SET_TRUEVAL accordingly.

Tested by compiling some test functions that use __atomic_test_and_set /
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL with various SH atomic option
combinations and looking at the output asm.

OK to apply to trunk?

Richard, could you also please take the
TARGET_ATOMIC_TEST_AND_SET_TRUEVAL hunk from this patch for the 4.7
branch?

Cheers,
Oleg


2012-03-04  Oleg Endo  olege...@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.
Index: gcc/doc/invoke.texi
===
--- gcc/doc/invoke.texi	(revision 184877)
+++ gcc/doc/invoke.texi	(working copy)
@@ -887,7 +887,8 @@
 -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
@@ -17823,6 +17824,15 @@
 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}.
Index: gcc/config/sh/sh.h
===
--- gcc/config/sh/sh.h	(revision 184877)
+++ gcc/config/sh/sh.h	(working copy)
@@ -2473,4 +2473,10 @@
 /* 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: gcc/config/sh/sync.md
===
--- gcc/config/sh/sync.md	(revision 184877)
+++ gcc/config/sh/sync.md	(working copy)
@@ -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 

Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-04 Thread Kaz Kojima
Oleg Endo oleg.e...@t-online.de wrote:
 Attached is a slightly modified version of the patch from
 http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00085.html
 
 I have removed the signed char weirdo and adjusted the comment above
 TARGET_ATOMIC_TEST_AND_SET_TRUEVAL accordingly.
 
 Tested by compiling some test functions that use __atomic_test_and_set /
 __GCC_ATOMIC_TEST_AND_SET_TRUEVAL with various SH atomic option
 combinations and looking at the output asm.
 
 OK to apply to trunk?

OK.

Regards,
kaz


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-03 Thread Richard Henderson
On 03/02/2012 10:11 AM, Richard Henderson wrote:
 I'm in the process of sanity testing this on x86_64 with trueval set to 0x80.
 Jakub, ok for 4.7 branch if it passes?
 
   * optabs.c (expand_atomic_test_and_set): Honor
   atomic_test_and_set_trueval even when atomic_test_and_set
   optab is not in use.

I've committed this patch to mainline.  I still think it ought to 
go onto the 4.7 branch...


r~


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-03 Thread Jakub Jelinek
On Sat, Mar 03, 2012 at 10:31:17AM -0800, Richard Henderson wrote:
 On 03/02/2012 10:11 AM, Richard Henderson wrote:
  I'm in the process of sanity testing this on x86_64 with trueval set to 
  0x80.
  Jakub, ok for 4.7 branch if it passes?
  
  * optabs.c (expand_atomic_test_and_set): Honor
  atomic_test_and_set_trueval even when atomic_test_and_set
  optab is not in use.
 
 I've committed this patch to mainline.  I still think it ought to 
 go onto the 4.7 branch...

Ok.

Jakub


[4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-02 Thread Richard Henderson
On 02/28/2012 07:16 AM, Oleg Endo wrote:
 Wouldn't it make sense to use the value behind
 TARGET_ATOMIC_TEST_AND_SET_TRUEVAL in optabs.c
 (expand_atomic_test_and_set) instead of const1_rtx when emitting
 generated atomic_exchange / atomic_compare_and_swap_exchange_loop?
 Maybe something like the attached patch?
 
 Background:
 I'm working on a patch to add a new option -menable-tas (independent of
 the existing -msoft-atomic option) which would allow the compiler to
 generate SH's tas.b insn.  This would allow using the tas.b insn without
 the other atomic sequences, or in combination with them.  The reason
 behind this is that the tas.b insn might not always be appropriate to
 use, depending on the particular system hardware/software setup (e.g.
 dual-core SH4A).
 On SH the TARGET_ATOMIC_TEST_AND_SET_TRUEVAL has to be defined as 0x80.
 Having the generated atomic_compare_and_swap / atomic_exchange sequences
 using 0x01 as the 'set' value might lead to inconsistencies when mixing
 code that uses the tas.b insn and code that doesn't use it, which should
 actually be OK to do.

That's a good idea.

For proper binary compatibility, we should probably introduce that asap.
You forgot two things in your patch, gen_int_mode and the fact that we
still have to return a boolean (0/1) value.

Also in order for the binary compatibility to work right, you'd want to
have the SH test-and-set-trueval set appropriately asap.  Kaz, I assume
you'd agree that 0x80 is a good value for the tas.b insn?  We don't
necessarily need to support tas.b right away, but getting trueval set
right is imperative.

I'm in the process of sanity testing this on x86_64 with trueval set to 0x80.
Jakub, ok for 4.7 branch if it passes?


r~
* optabs.c (expand_atomic_test_and_set): Honor
atomic_test_and_set_trueval even when atomic_test_and_set
optab is not in use.



diff --git a/gcc/optabs.c b/gcc/optabs.c
index b0ecdf0..fd353d7 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -7384,34 +7384,57 @@ rtx
 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
 {
   enum machine_mode mode = GET_MODE (mem);
-  rtx ret;
+  rtx ret, trueval, subtarget;
 
   ret = maybe_emit_atomic_test_and_set (target, mem, model);
   if (ret)
 return ret;
 
-  if (target == NULL_RTX)
-target = gen_reg_rtx (mode);
+  /* Be binary compatible with non-default settings of trueval, and different
+ cpu revisions.  E.g. one revision may have atomic-test-and-set, but
+ another only has atomic-exchange.  */
+  if (targetm.atomic_test_and_set_trueval == 1)
+{
+  trueval = const1_rtx;
+  subtarget = target ? target : gen_reg_rtx (mode);
+}
+  else
+{
+  trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
+  subtarget = gen_reg_rtx (mode);
+}
 
-  /* If there is no test and set, try exchange, then a compare_and_swap loop,
- then __sync_test_and_set.  */
-  ret = maybe_emit_atomic_exchange (target, mem, const1_rtx, model);
-  if (ret)
-return ret;
+  /* Try the atomic-exchange optab...  */
+  ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
 
-  ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, const1_rtx);
-  if (ret)
-return ret;
+  /* ... then an atomic-compare-and-swap loop ... */
+  if (!ret)
+ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
 
-  ret = maybe_emit_sync_lock_test_and_set (target, mem, const1_rtx, model);
-  if (ret)
-return ret;
+  /* ... before trying the vaguely defined legacy lock_test_and_set. */
+  if (!ret)
+ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
 
-  /* Failing all else, assume a single threaded environment and simply perform
- the operation.  */
-  emit_move_insn (target, mem);
-  emit_move_insn (mem, const1_rtx);
-  return target;
+  /* Recall that the legacy lock_test_and_set optab was allowed to do magic
+ things with the value 1.  Thus we try again without trueval.  */
+  if (!ret  targetm.atomic_test_and_set_trueval != 1)
+ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, 
model);
+
+  /* Failing all else, assume a single threaded environment and simply
+ perform the operation.  */
+  if (!ret)
+{
+  emit_move_insn (subtarget, mem);
+  emit_move_insn (mem, trueval);
+  ret = subtarget;
+}
+
+  /* Recall that have to return a boolean value; rectify if trueval
+ is not exactly one.  */
+  if (targetm.atomic_test_and_set_trueval != 1)
+ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
+  
+  return ret;
 }
 
 /* This function expands the atomic exchange operation:


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-02 Thread Oleg Endo
On Fri, 2012-03-02 at 10:11 -0800, Richard Henderson wrote:

 For proper binary compatibility, we should probably introduce that asap.
 You forgot two things in your patch, gen_int_mode and the fact that we
 still have to return a boolean (0/1) value.

Ah, yes, of course!

 
 Also in order for the binary compatibility to work right, you'd want to
 have the SH test-and-set-trueval set appropriately asap.  Kaz, I assume
 you'd agree that 0x80 is a good value for the tas.b insn?  We don't
 necessarily need to support tas.b right away, but getting trueval set
 right is imperative.
 
 I'm in the process of sanity testing this on x86_64 with trueval set to 0x80.
 Jakub, ok for 4.7 branch if it passes?
 

Since we're now back to stage 1 again, I'm about to commit this one ...
http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00085.html

So the SH tas.b instruction support should be there from 4.8.
Attached is the hunk from the tas.b patch for 4.8 to define
TARGET_ATOMIC_TEST_AND_SET_TRUEVAL.

Cheers,
Oleg
Index: gcc/config/sh/sh.h
===
--- gcc/config/sh/sh.h	(revision 184669)
+++ gcc/config/sh/sh.h	(working copy)
@@ -2475,4 +2475,11 @@
 /* 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.  It must be defined as signed char here or else the movqi
+   pattern will refuse to load it as a QImode constant.  */
+#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
+#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL ((signed char)0x80)
+
 #endif /* ! GCC_SH_H */



Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-02 Thread Richard Henderson
On 03/02/2012 12:27 PM, Oleg Endo wrote:
 +   This value is used by optabs.c atomic op expansion code as well as in 
 +   sync.md.  It must be defined as signed char here or else the movqi
 +   pattern will refuse to load it as a QImode constant.  */
 +#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
 +#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL ((signed char)0x80)

The fix to use gen_mode_int obviates the need for the (signed char) hack.


r~


Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-02 Thread Oleg Endo
On Fri, 2012-03-02 at 12:34 -0800, Richard Henderson wrote:
 On 03/02/2012 12:27 PM, Oleg Endo wrote:
  +   This value is used by optabs.c atomic op expansion code as well as in 
  +   sync.md.  It must be defined as signed char here or else the movqi
  +   pattern will refuse to load it as a QImode constant.  */
  +#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
  +#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL ((signed char)0x80)
 
 The fix to use gen_mode_int obviates the need for the (signed char) hack.
 

Ah right, sorry again.
Then I'll rather wait with the whole tas.b patch until the optabs
changes are in.

Cheers,
Oleg



Re: [4.7][SH] Binary compatibility with atomic_test_and_test_trueval != 1

2012-03-02 Thread Kaz Kojima
Richard Henderson r...@redhat.com wrote:
 For proper binary compatibility, we should probably introduce that asap.
 You forgot two things in your patch, gen_int_mode and the fact that we
 still have to return a boolean (0/1) value.
 
 Also in order for the binary compatibility to work right, you'd want to
 have the SH test-and-set-trueval set appropriately asap.  Kaz, I assume
 you'd agree that 0x80 is a good value for the tas.b insn?  We don't
 necessarily need to support tas.b right away, but getting trueval set
 right is imperative.

Yes, 0x80 is an appropriate value as you and oleg have suggested.

Regards,
kaz