hexagon.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. #include "../all_aligned_atomic_load_store.h"
  12. #include "../test_and_set_t_is_ao_t.h"
  13. /* There's also "isync" and "barrier"; however, for all current CPU */
  14. /* versions, "syncht" should suffice. Likewise, it seems that the */
  15. /* auto-defined versions of *_acquire, *_release or *_full suffice for */
  16. /* all current ISA implementations. */
  17. AO_INLINE void
  18. AO_nop_full(void)
  19. {
  20. __asm__ __volatile__("syncht" : : : "memory");
  21. }
  22. #define AO_HAVE_nop_full
  23. /* The Hexagon has load-locked, store-conditional primitives, and so */
  24. /* resulting code is very nearly identical to that of PowerPC. */
  25. #ifndef AO_PREFER_GENERALIZED
  26. AO_INLINE AO_t
  27. AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
  28. {
  29. AO_t oldval;
  30. AO_t newval;
  31. __asm__ __volatile__(
  32. "1:\n"
  33. " %0 = memw_locked(%3);\n" /* load and reserve */
  34. " %1 = add (%0,%4);\n" /* increment */
  35. " memw_locked(%3,p1) = %1;\n" /* store conditional */
  36. " if (!p1) jump 1b;\n" /* retry if lost reservation */
  37. : "=&r"(oldval), "=&r"(newval), "+m"(*addr)
  38. : "r"(addr), "r"(incr)
  39. : "memory", "p1");
  40. return oldval;
  41. }
  42. #define AO_HAVE_fetch_and_add
  43. AO_INLINE AO_TS_VAL_t
  44. AO_test_and_set(volatile AO_TS_t *addr)
  45. {
  46. int oldval;
  47. int locked_value = 1;
  48. __asm__ __volatile__(
  49. "1:\n"
  50. " %0 = memw_locked(%2);\n" /* load and reserve */
  51. " {\n"
  52. " p2 = cmp.eq(%0,#0);\n" /* if load is not zero, */
  53. " if (!p2.new) jump:nt 2f; \n" /* we are done */
  54. " }\n"
  55. " memw_locked(%2,p1) = %3;\n" /* else store conditional */
  56. " if (!p1) jump 1b;\n" /* retry if lost reservation */
  57. "2:\n" /* oldval is zero if we set */
  58. : "=&r"(oldval), "+m"(*addr)
  59. : "r"(addr), "r"(locked_value)
  60. : "memory", "p1", "p2");
  61. return (AO_TS_VAL_t)oldval;
  62. }
  63. #define AO_HAVE_test_and_set
  64. #endif /* !AO_PREFER_GENERALIZED */
  65. #ifndef AO_GENERALIZE_ASM_BOOL_CAS
  66. AO_INLINE int
  67. AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
  68. {
  69. AO_t __oldval;
  70. int result = 0;
  71. __asm__ __volatile__(
  72. "1:\n"
  73. " %0 = memw_locked(%3);\n" /* load and reserve */
  74. " {\n"
  75. " p2 = cmp.eq(%0,%4);\n" /* if load is not equal to */
  76. " if (!p2.new) jump:nt 2f; \n" /* old, fail */
  77. " }\n"
  78. " memw_locked(%3,p1) = %5;\n" /* else store conditional */
  79. " if (!p1) jump 1b;\n" /* retry if lost reservation */
  80. " %1 = #1\n" /* success, result = 1 */
  81. "2:\n"
  82. : "=&r" (__oldval), "+r" (result), "+m"(*addr)
  83. : "r" (addr), "r" (old), "r" (new_val)
  84. : "p1", "p2", "memory"
  85. );
  86. return result;
  87. }
  88. # define AO_HAVE_compare_and_swap
  89. #endif /* !AO_GENERALIZE_ASM_BOOL_CAS */
  90. AO_INLINE AO_t
  91. AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
  92. {
  93. AO_t __oldval;
  94. __asm__ __volatile__(
  95. "1:\n"
  96. " %0 = memw_locked(%2);\n" /* load and reserve */
  97. " {\n"
  98. " p2 = cmp.eq(%0,%3);\n" /* if load is not equal to */
  99. " if (!p2.new) jump:nt 2f; \n" /* old_val, fail */
  100. " }\n"
  101. " memw_locked(%2,p1) = %4;\n" /* else store conditional */
  102. " if (!p1) jump 1b;\n" /* retry if lost reservation */
  103. "2:\n"
  104. : "=&r" (__oldval), "+m"(*addr)
  105. : "r" (addr), "r" (old_val), "r" (new_val)
  106. : "p1", "p2", "memory"
  107. );
  108. return __oldval;
  109. }
  110. #define AO_HAVE_fetch_compare_and_swap
  111. #define AO_T_IS_INT