2 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
3 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
12 #include "../all_aligned_atomic_load_store.h"
14 #include "../test_and_set_t_is_ao_t.h"
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. */
23 __asm__ __volatile__("syncht" : : : "memory");
25 #define AO_HAVE_nop_full
27 /* The Hexagon has load-locked, store-conditional primitives, and so */
28 /* resulting code is very nearly identical to that of PowerPC. */
31 AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
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)
46 #define AO_HAVE_fetch_and_add
49 AO_test_and_set(volatile AO_TS_t *addr)
56 " %0 = memw_locked(%2);\n" /* load and reserve */
58 " p2 = cmp.eq(%0,#0);\n" /* if load is not zero, */
59 " if (!p2.new) jump:nt 2f; \n" /* we are done */
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;
69 #define AO_HAVE_test_and_set
72 AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
78 " %0 = memw_locked(%3);\n" /* load and reserve */
80 " p2 = cmp.eq(%0,%4);\n" /* if load is not equal to */
81 " if (!p2.new) jump:nt 2f; \n" /* old, fail */
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 */
87 : "=&r" (__oldval), "+r" (result), "+m"(*addr)
88 : "r" (addr), "r" (old), "r" (new_val)
89 : "p1", "p2", "memory"
93 #define AO_HAVE_compare_and_swap
95 /* Generalize first to define more AO_int_... primitives. */
96 #include "../../generalize.h"
98 #include "../ao_t_is_int.h"