And I propose this for the basic functionality tests. (I'm not using the
one Aldy had in the original patch anymore)
'sync-mem.h' provides the bits required to test the existence and basic
functionality of a sync_mem_exchange with all the valid memory models.
All it is missing is a declaration of the type.
sync-mem[1-5].c define a type and then include sync-mem.h to test each
of 1, 2, 4, 8, and 16 byte variations. I did it this way since there
are different dejagnu options and stuff for each of the different sizes,
especially the 16 byte variation.
sync-mem-invalid.c tests for compiler generated errors when invalid
memory models are specified.
As new sync memory model built-ins are defined, they just need to add a
routine to sync-mem.h to test the valid memory models, and
add an entry to sync-mem-invalid for each invalid mode.
I'll properly fill in the supported hardware for
'check_effective_target_sync_int_128' and
'check_effective_target_sync_long_long' once I get around to figuring
them out.
Seem reasonable? May shuffle stuff around later, but this is a start.
Andrew
* lib/target-support.exp (check_effective_target_sync_int_128,
check_effective_target_sync_long_long): Check whether the target
supports 64 and 128 bit __sync builtins.
* gcc.dg/sync-mem.h: New. Common code to check memory model __syncs.
* gcc.dg/sync-mem-1.c: New. Check char size.
* gcc.dg/sync-mem-2.c: New. Check short size.
* gcc.dg/sync-mem-3.c: New. Check int size.
* gcc.dg/sync-mem-4.c: New. Check long long.
* gcc.dg/sync-mem-5.c: New. Check 128 bit.
* gcc.dg/sync-mem-invalid.c: New. Check invalid memory modes.
Index: lib/target-supports.exp
===================================================================
*** lib/target-supports.exp (revision 175229)
--- lib/target-supports.exp (working copy)
*************** proc check_effective_target_section_anch
*** 3272,3277 ****
--- 3272,3313 ----
return $et_section_anchors_saved
}
+ # Return 1 if the target supports atomic operations on "int_128" values.
+
+ proc check_effective_target_sync_int_128 { } {
+ global et_sync_int_128_saved
+
+ if [info exists et_sync_int_128_saved] {
+ verbose "check_effective_target_sync_int_128: using cached result" 2
+ } else {
+ set et_sync_int_128_saved 0
+ if { [istarget x86_64-*-*] } {
+ set et_sync_int_128_saved 1
+ }
+ }
+
+ verbose "check_effective_target_sync_int_128: returning
$et_sync_int_128_saved" 2
+ return $et_sync_int_128_saved
+ }
+
+ # Return 1 if the target supports atomic operations on "long long".
+
+ proc check_effective_target_sync_long_long { } {
+ global et_sync_long_long_saved
+
+ if [info exists et_sync_long_long_saved] {
+ verbose "check_effective_target_sync_long_long: using cached result" 2
+ } else {
+ set et_sync_long_long_saved 0
+ if { [istarget x86_64-*-*] } {
+ set et_sync_long_long_saved 1
+ }
+ }
+
+ verbose "check_effective_target_sync_long_long: returning
$et_sync_long_long_saved" 2
+ return $et_sync_long_long_saved
+ }
+
# Return 1 if the target supports atomic operations on "int" and "long".
proc check_effective_target_sync_int_long { } {
Index: gcc.dg/sync-mem.h
===================================================================
*** gcc.dg/sync-mem.h (revision 0)
--- gcc.dg/sync-mem.h (revision 0)
***************
*** 0 ****
--- 1,27 ----
+ /* Define all the __sync verifications here. Each size variation to be tested
+ will define 'TYPE' and then include this file. */
+
+ extern void abort(void);
+
+ TYPE v, count;
+
+ #define EXCHANGE(VAR, MODE) if (__sync_mem_exchange (&VAR, count + 1, MODE)
\
+ != count++) abort()
+ void test_exchange()
+ {
+ v = 0;
+ count = 0;
+ EXCHANGE (v, __SYNC_MEM_RELAXED);
+ EXCHANGE (v, __SYNC_MEM_ACQUIRE);
+ EXCHANGE (v, __SYNC_MEM_RELEASE);
+ EXCHANGE (v, __SYNC_MEM_ACQ_REL);
+ EXCHANGE (v, __SYNC_MEM_SEQ_CST);
+ }
+
+
+
+ main ()
+ {
+ test_exchange();
+ return 0;
+ }
Index: gcc.dg/sync-mem-1.c
===================================================================
*** gcc.dg/sync-mem-1.c (revision 0)
--- gcc.dg/sync-mem-1.c (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* Test __sync_mem routines for existence and proper execution on 1 byte
+ values with each valid memory model. */
+ /* { dg-do run } */
+ /* { dg-require-effective-target sync_char_short } */
+
+ #define TYPE char
+
+ #include "sync-mem.h"
Index: gcc.dg/sync-mem-2.c
===================================================================
*** gcc.dg/sync-mem-2.c (revision 0)
--- gcc.dg/sync-mem-2.c (revision 0)
***************
*** 0 ****
--- 1,9 ----
+ /* Test __sync_mem routines for existence and proper execution on 2 byte
+ values with each valid memory model. */
+ /* { dg-do run } */
+ /* { dg-require-effective-target sync_char_short } */
+
+ #define TYPE short
+
+ #include "sync-mem.h"
+
Index: gcc.dg/sync-mem-3.c
===================================================================
*** gcc.dg/sync-mem-3.c (revision 0)
--- gcc.dg/sync-mem-3.c (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* Test __sync_mem routines for existence and proper execution on 4 byte
+ values with each valid memory model. */
+ /* { dg-do run } */
+ /* { dg-require-effective-target sync_int_long } */
+
+ #define TYPE long
+
+ #include "sync-mem.h"
Index: gcc.dg/sync-mem-4.c
===================================================================
*** gcc.dg/sync-mem-4.c (revision 0)
--- gcc.dg/sync-mem-4.c (revision 0)
***************
*** 0 ****
--- 1,9 ----
+ /* Test __sync_mem routines for existence and proper execution on 8 byte
+ values with each valid memory model. */
+ /* { dg-do run } */
+ /* { dg-require-effective-target sync_long_long } */
+ /* { dg-options "" } */
+
+ #define TYPE long long
+
+ #include "sync-mem.h"
Index: gcc.dg/sync-mem-5.c
===================================================================
*** gcc.dg/sync-mem-5.c (revision 0)
--- gcc.dg/sync-mem-5.c (revision 0)
***************
*** 0 ****
--- 1,9 ----
+ /* Test __sync_mem routines for existence and proper execution on 16 byte
+ values with each valid memory model. */
+ /* { dg-do run } */
+ /* { dg-require-effective-target sync_int_128 } */
+ /* { dg-options "-mcx16" { target { x86_64-*-* } } } */
+
+ #define TYPE __int128_t
+
+ #include "sync-mem.h"
Index: gcc.dg/sync-mem-invalid.c
===================================================================
*** gcc.dg/sync-mem-invalid.c (revision 0)
--- gcc.dg/sync-mem-invalid.c (revision 0)
***************
*** 0 ****
--- 1,11 ----
+ /* Test __sync_mem routines for invalid memory model errors. This only needs
+ to be tested on a single size. */
+ /* { dg-do compile } */
+ /* { dg-require-effective-target sync_int_long } */
+
+ int i;
+
+ main ()
+ {
+ __sync_mem_exchange (&i, 1, __SYNC_MEM_CONSUME); /* { dg-error "invalid
memory model" } */
+ }