(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
di-longlong64-sync-1.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target sync_long_long_runtime } */
       3  /* { dg-options "-std=gnu99" } */
       4  /* { dg-additional-options "-march=pentium" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
       5  
       6  /* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */
       7  /* { dg-message "note: '__sync_nand_and_fetch' changed semantics in GCC 4.4" "nand_and_fetch" { target *-*-* } 0 } */
       8  
       9  
      10  /* Test basic functionality of the intrinsics.  The operations should
      11     not be optimized away if no one checks the return values.  */
      12  
      13  /* Based on ia64-sync-[12].c, but 1) long on ARM is 32 bit so use long long
      14     (an explicit 64bit type maybe a better bet) and 2) Use values that cross
      15     the 32bit boundary and cause carries since the actual maths are done as
      16     pairs of 32 bit instructions.  */
      17  
      18  /* Note: This file is #included by some of the ARM tests.  */
      19  
      20  __extension__ typedef __SIZE_TYPE__ size_t;
      21  
      22  extern void abort (void);
      23  extern void *memcpy (void *, const void *, size_t);
      24  extern int memcmp (const void *, const void *, size_t);
      25  
      26  /* Temporary space where the work actually gets done.  */
      27  static long long AL[24];
      28  /* Values copied into AL before we start.  */
      29  static long long init_di[24] = { 0x100000002ll, 0x200000003ll, 0, 1,
      30  
      31  				 0x100000002ll, 0x100000002ll,
      32  				 0x100000002ll, 0x100000002ll,
      33  
      34  				 0, 0x1000e0de0000ll,
      35  				 42 , 0xc001c0de0000ll,
      36  
      37  				 -1ll, 0, 0xff00ff0000ll, -1ll,
      38  
      39  				 0, 0x1000e0de0000ll,
      40  				 42 , 0xc001c0de0000ll,
      41  
      42  				 -1ll, 0, 0xff00ff0000ll, -1ll};
      43  /* This is what should be in AL at the end.  */
      44  static long long test_di[24] = { 0x1234567890ll, 0x1234567890ll, 1, 0,
      45  
      46  				 0x100000002ll, 0x100000002ll,
      47  				 0x100000002ll, 0x100000002ll,
      48  
      49  				 1, 0xc001c0de0000ll,
      50  				 20, 0x1000e0de0000ll,
      51  
      52  				 0x300000007ll , 0x500000009ll,
      53  				 0xf100ff0001ll, ~0xa00000007ll,
      54  
      55  				 1, 0xc001c0de0000ll,
      56  				 20, 0x1000e0de0000ll,
      57  
      58  				 0x300000007ll , 0x500000009ll,
      59  				 0xf100ff0001ll, ~0xa00000007ll };
      60  
      61  /* First check they work in terms of what they do to memory.  */
      62  static void
      63  do_noret_di (void)
      64  {
      65    __sync_val_compare_and_swap (AL+0, 0x100000002ll, 0x1234567890ll);
      66    __sync_bool_compare_and_swap (AL+1, 0x200000003ll, 0x1234567890ll);
      67    __sync_lock_test_and_set (AL+2, 1);
      68    __sync_lock_release (AL+3);
      69  
      70    /* The following tests should not change the value since the
      71       original does NOT match.  */
      72    __sync_val_compare_and_swap (AL+4, 0x000000002ll, 0x1234567890ll);
      73    __sync_val_compare_and_swap (AL+5, 0x100000000ll, 0x1234567890ll);
      74    __sync_bool_compare_and_swap (AL+6, 0x000000002ll, 0x1234567890ll);
      75    __sync_bool_compare_and_swap (AL+7, 0x100000000ll, 0x1234567890ll);
      76  
      77    __sync_fetch_and_add (AL+8, 1);
      78    __sync_fetch_and_add (AL+9, 0xb000e0000000ll); /* + to both halves & carry.  */
      79    __sync_fetch_and_sub (AL+10, 22);
      80    __sync_fetch_and_sub (AL+11, 0xb000e0000000ll);
      81  
      82    __sync_fetch_and_and (AL+12, 0x300000007ll);
      83    __sync_fetch_and_or (AL+13, 0x500000009ll);
      84    __sync_fetch_and_xor (AL+14, 0xe00000001ll);
      85    __sync_fetch_and_nand (AL+15, 0xa00000007ll);
      86  
      87    /* These should be the same as the fetch_and_* cases except for
      88       return value.  */
      89    __sync_add_and_fetch (AL+16, 1);
      90    /* add to both halves & carry.  */
      91    __sync_add_and_fetch (AL+17, 0xb000e0000000ll);
      92    __sync_sub_and_fetch (AL+18, 22);
      93    __sync_sub_and_fetch (AL+19, 0xb000e0000000ll);
      94  
      95    __sync_and_and_fetch (AL+20, 0x300000007ll);
      96    __sync_or_and_fetch (AL+21, 0x500000009ll);
      97    __sync_xor_and_fetch (AL+22, 0xe00000001ll);
      98    __sync_nand_and_fetch (AL+23, 0xa00000007ll);
      99  }
     100  
     101  /* Now check return values.  */
     102  static void
     103  do_ret_di (void)
     104  {
     105    if (__sync_val_compare_and_swap (AL+0, 0x100000002ll, 0x1234567890ll) !=
     106  	0x100000002ll) abort ();
     107    if (__sync_bool_compare_and_swap (AL+1, 0x200000003ll, 0x1234567890ll) !=
     108  	1) abort ();
     109    if (__sync_lock_test_and_set (AL+2, 1) != 0) abort ();
     110    __sync_lock_release (AL+3); /* no return value, but keep to match results.  */
     111  
     112    /* The following tests should not change the value since the
     113       original does NOT match.  */
     114    if (__sync_val_compare_and_swap (AL+4, 0x000000002ll, 0x1234567890ll) !=
     115  	0x100000002ll) abort ();
     116    if (__sync_val_compare_and_swap (AL+5, 0x100000000ll, 0x1234567890ll) !=
     117  	0x100000002ll) abort ();
     118    if (__sync_bool_compare_and_swap (AL+6, 0x000000002ll, 0x1234567890ll) !=
     119  	0) abort ();
     120    if (__sync_bool_compare_and_swap (AL+7, 0x100000000ll, 0x1234567890ll) !=
     121  	0) abort ();
     122  
     123    if (__sync_fetch_and_add (AL+8, 1) != 0) abort ();
     124    if (__sync_fetch_and_add (AL+9, 0xb000e0000000ll) != 0x1000e0de0000ll) abort ();
     125    if (__sync_fetch_and_sub (AL+10, 22) != 42) abort ();
     126    if (__sync_fetch_and_sub (AL+11, 0xb000e0000000ll) != 0xc001c0de0000ll)
     127  	abort ();
     128  
     129    if (__sync_fetch_and_and (AL+12, 0x300000007ll) != -1ll) abort ();
     130    if (__sync_fetch_and_or (AL+13, 0x500000009ll) != 0) abort ();
     131    if (__sync_fetch_and_xor (AL+14, 0xe00000001ll) != 0xff00ff0000ll) abort ();
     132    if (__sync_fetch_and_nand (AL+15, 0xa00000007ll) != -1ll) abort ();
     133  
     134    /* These should be the same as the fetch_and_* cases except for
     135       return value.  */
     136    if (__sync_add_and_fetch (AL+16, 1) != 1) abort ();
     137    if (__sync_add_and_fetch (AL+17, 0xb000e0000000ll) != 0xc001c0de0000ll)
     138  	abort ();
     139    if (__sync_sub_and_fetch (AL+18, 22) != 20) abort ();
     140    if (__sync_sub_and_fetch (AL+19, 0xb000e0000000ll) != 0x1000e0de0000ll)
     141  	abort ();
     142  
     143    if (__sync_and_and_fetch (AL+20, 0x300000007ll) != 0x300000007ll) abort ();
     144    if (__sync_or_and_fetch (AL+21, 0x500000009ll) != 0x500000009ll) abort ();
     145    if (__sync_xor_and_fetch (AL+22, 0xe00000001ll) != 0xf100ff0001ll) abort ();
     146    if (__sync_nand_and_fetch (AL+23, 0xa00000007ll) != ~0xa00000007ll) abort ();
     147  }
     148  
     149  int main ()
     150  {
     151    memcpy (AL, init_di, sizeof (init_di));
     152  
     153    do_noret_di ();
     154  
     155    if (memcmp (AL, test_di, sizeof (test_di)))
     156      abort ();
     157  
     158    memcpy (AL, init_di, sizeof (init_di));
     159  
     160    do_ret_di ();
     161  
     162    if (memcmp (AL, test_di, sizeof (test_di)))
     163      abort ();
     164  
     165    return 0;
     166  }