atomic.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (C) 2016-2017 Andes Technology, Inc.
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. #ifndef _NDS32_BITS_ATOMIC_H
  6. #define _NDS32_BITS_ATOMIC_H
  7. #include <stdint.h>
  8. typedef int8_t atomic8_t;
  9. typedef uint8_t uatomic8_t;
  10. typedef int_fast8_t atomic_fast8_t;
  11. typedef uint_fast8_t uatomic_fast8_t;
  12. typedef int16_t atomic16_t;
  13. typedef uint16_t uatomic16_t;
  14. typedef int_fast16_t atomic_fast16_t;
  15. typedef uint_fast16_t uatomic_fast16_t;
  16. typedef int32_t atomic32_t;
  17. typedef uint32_t uatomic32_t;
  18. typedef int_fast32_t atomic_fast32_t;
  19. typedef uint_fast32_t uatomic_fast32_t;
  20. typedef int64_t atomic64_t;
  21. typedef uint64_t uatomic64_t;
  22. typedef int_fast64_t atomic_fast64_t;
  23. typedef uint_fast64_t uatomic_fast64_t;
  24. typedef intptr_t atomicptr_t;
  25. typedef uintptr_t uatomicptr_t;
  26. typedef intmax_t atomic_max_t;
  27. typedef uintmax_t uatomic_max_t;
  28. #ifndef atomic_full_barrier
  29. # define atomic_full_barrier() __asm__ ("dsb" ::: "memory")
  30. #endif
  31. #ifndef atomic_read_barrier
  32. # define atomic_read_barrier() atomic_full_barrier ()
  33. #endif
  34. #ifndef atomic_write_barrier
  35. # define atomic_write_barrier() atomic_full_barrier ()
  36. #endif
  37. #define atomic_exchange_acq(mem, newval) \
  38. ({ unsigned long val, offset, temp; \
  39. \
  40. __asm__ volatile ( \
  41. "move %2, %4\n\t" \
  42. "move %1, #0x0\n\t" \
  43. "1:\n\t" \
  44. "llw %0, [%3 + %1 << 0]\n\t" \
  45. "move %2, %4\n\t" \
  46. "scw %2, [%3 + %1 << 0]\n\t" \
  47. "beqz %2, 1b\n\t" \
  48. : "=&r" (val), "=&r" (offset), "=&r" (temp) \
  49. : "r" (mem), "r" (newval) \
  50. : "memory" ); \
  51. val; })
  52. #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
  53. ({ unsigned long val, offset, temp; \
  54. \
  55. __asm__ volatile ( \
  56. "move %1, #0x0\n\t" \
  57. "move %2, %4\n\t" \
  58. "1:\n\t" \
  59. "llw %0, [%3 + %1 << 0]\n\t" \
  60. "bne %0, %5, 2f\n\t" \
  61. "move %2, %4\n\t" \
  62. "scw %2, [%3 + %1 << 0]\n\t" \
  63. "beqz %2, 1b\n\t" \
  64. "j 3f\n\t" \
  65. "2:\n\t" \
  66. "move %2, %0\n\t" \
  67. "scw %2, [%3 + %1 << 0]\n\t" \
  68. "3:\n\t" \
  69. : "=&r" (val), "=&r" (offset), "=&r" (temp) \
  70. : "r" (mem), "r" (newval), "r" (oldval) \
  71. : "memory" ); \
  72. val; })
  73. #define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
  74. ({ unsigned long val, offset, temp; \
  75. \
  76. __asm__ volatile ( \
  77. "move %1, #0x0\n\t" \
  78. "move %2, %4\n\t" \
  79. "1:\n\t" \
  80. "llw %0, [%3 + %1 << 0]\n\t" \
  81. "bne %5, %0, 2f\n\t" \
  82. "move %2, %4\n\t" \
  83. "scw %2, [%3 + %1 << 0]\n\t" \
  84. "beqz %2, 1b\n\t" \
  85. "addi %0, %1, #0\n\t" \
  86. "j 3f\n\t" \
  87. "2:\n\t" \
  88. "scw %0, [%3 + %1 << 0]\n\t" \
  89. "addi %0, %1, #0x1\n\t" \
  90. "3:\n\t" \
  91. : "=&r" (val), "=&r" (offset), "=&r" (temp) \
  92. : "r" (mem), "r" (newval), "r" (oldval) \
  93. : "memory" ); \
  94. val; })
  95. #endif