implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / libatomic_ops / src / atomic_ops / sysdeps / gcc / hexagon.h
1 /*
2  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
3  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
4  *
5  * Permission is hereby granted to use or copy this program
6  * for any purpose,  provided the above notices are retained on all copies.
7  * Permission to modify the code and to distribute modified code is granted,
8  * provided the above notices are retained, and a notice that the code was
9  * modified is included with the above copyright notice.
10  */
11
12 #include "../all_aligned_atomic_load_store.h"
13
14 #include "../test_and_set_t_is_ao_t.h"
15
16 /* There's also "isync" and "barrier"; however, for all current CPU     */
17 /* versions, "syncht" should suffice.  Likewise, it seems that the      */
18 /* auto-defined versions of *_acquire, *_release or *_full suffice for  */
19 /* all current ISA implementations.                                     */
20 AO_INLINE void
21 AO_nop_full(void)
22 {
23   __asm__ __volatile__("syncht" : : : "memory");
24 }
25 #define AO_HAVE_nop_full
26
27 /* The Hexagon has load-locked, store-conditional primitives, and so    */
28 /* resulting code is very nearly identical to that of PowerPC.          */
29
30 AO_INLINE AO_t
31 AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
32 {
33   AO_t oldval;
34   AO_t newval;
35   __asm__ __volatile__(
36      "1:\n"
37      "  %0 = memw_locked(%3);\n"        /* load and reserve            */
38      "  %1 = add (%0,%4);\n"            /* increment                   */
39      "  memw_locked(%3,p1) = %1;\n"     /* store conditional           */
40      "  if (!p1) jump 1b;\n"            /* retry if lost reservation   */
41      : "=&r"(oldval), "=&r"(newval), "+m"(*addr)
42      : "r"(addr), "r"(incr)
43      : "memory", "p1");
44   return oldval;
45 }
46 #define AO_HAVE_fetch_and_add
47
48 AO_INLINE AO_TS_VAL_t
49 AO_test_and_set(volatile AO_TS_t *addr)
50 {
51   int oldval;
52   int locked_value = 1;
53
54   __asm__ __volatile__(
55      "1:\n"
56      "  %0 = memw_locked(%2);\n"        /* load and reserve            */
57      "  {\n"
58      "    p2 = cmp.eq(%0,#0);\n"        /* if load is not zero,        */
59      "    if (!p2.new) jump:nt 2f; \n"  /* we are done                 */
60      "  }\n"
61      "  memw_locked(%2,p1) = %3;\n"     /* else store conditional      */
62      "  if (!p1) jump 1b;\n"            /* retry if lost reservation   */
63      "2:\n"                             /* oldval is zero if we set    */
64      : "=&r"(oldval), "+m"(*addr)
65      : "r"(addr), "r"(locked_value)
66      : "memory", "p1", "p2");
67   return (AO_TS_VAL_t)oldval;
68 }
69 #define AO_HAVE_test_and_set
70
71 AO_INLINE int
72 AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
73 {
74   AO_t __oldval;
75   int result = 0;
76   __asm__ __volatile__(
77      "1:\n"
78      "  %0 = memw_locked(%3);\n"        /* load and reserve            */
79      "  {\n"
80      "    p2 = cmp.eq(%0,%4);\n"        /* if load is not equal to     */
81      "    if (!p2.new) jump:nt 2f; \n"  /* old, fail                   */
82      "  }\n"
83      "  memw_locked(%3,p1) = %5;\n"     /* else store conditional      */
84      "  if (!p1) jump 1b;\n"            /* retry if lost reservation   */
85      "  %1 = #1\n"                      /* success, result = 1         */
86      "2:\n"
87      : "=&r" (__oldval), "+r" (result), "+m"(*addr)
88      : "r" (addr), "r" (old), "r" (new_val)
89      : "p1", "p2", "memory"
90   );
91   return result;
92 }
93 #define AO_HAVE_compare_and_swap
94
95 /* Generalize first to define more AO_int_... primitives.       */
96 #include "../../generalize.h"
97
98 #include "../ao_t_is_int.h"