atomic.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyrith (C) 2013 Imagination Technologies Ltd.
  3. *
  4. * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
  5. *
  6. */
  7. #include <stdint.h>
  8. #include <sysdep.h>
  9. typedef int8_t atomic8_t;
  10. typedef uint8_t uatomic8_t;
  11. typedef int_fast8_t atomic_fast8_t;
  12. typedef uint_fast8_t uatomic_fast8_t;
  13. typedef int32_t atomic32_t;
  14. typedef uint32_t uatomic32_t;
  15. typedef int_fast32_t atomic_fast32_t;
  16. typedef uint_fast32_t uatomic_fast32_t;
  17. typedef intptr_t atomicptr_t;
  18. typedef uintptr_t uatomicptr_t;
  19. typedef intmax_t atomic_max_t;
  20. typedef uintmax_t uatomic_max_t;
  21. void __metag_link_error (void);
  22. #define atomic_full_barrier() \
  23. __asm__ __volatile__("": : :"memory")
  24. /* Atomic compare and exchange. This sequence relies on the kernel to
  25. provide a compare and exchange operation which is atomic. */
  26. #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
  27. ({ __metag_link_error (); oldval; })
  28. #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
  29. ({ __metag_link_error (); oldval; })
  30. /* This code uses the kernel helper to do cmpxchg. It relies on the fact
  31. the helper code only clobbers D0Re0. */
  32. #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
  33. ({ register __typeof (oldval) a_current __asm__ ("D1Ar1"); \
  34. register __typeof (oldval) a_newval __asm__ ("D0Ar2") = (newval); \
  35. register __typeof (mem) a_ptr __asm__ ("D1Ar3") = (mem); \
  36. register __typeof (oldval) a_oldval __asm__ ("D0Ar4") = (oldval); \
  37. __asm__ __volatile__ \
  38. ("0:\n\t" \
  39. "GETD %[cur], [%[ptr]]\n\t" \
  40. "CMP %[cur], %[old]\n\t" \
  41. "BNE 1f\n\t" \
  42. "MOVT D1RtP, #0x6fff\n\t" \
  43. "ADD D1RtP, D1RtP, #0xf040\n\t" \
  44. "SWAP D1RtP, PC\n\t" \
  45. "MOV %[cur], %[old]\n\t" \
  46. "CMP D0Re0, #0\n\t" \
  47. "BNE 0b\n\t" \
  48. "1:" \
  49. : [cur] "=&r" (a_current) \
  50. : [new] "r" (a_newval), [ptr] "r" (a_ptr), \
  51. [old] "r" (a_oldval) \
  52. : "D0Re0", "D1RtP", "cc", "memory"); \
  53. a_current; })
  54. #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
  55. ({ __metag_link_error (); oldval; })