/vendor/gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc/powerpc.h

http://github.com/feyeleanor/RubyGoLightly · C++ Header · 126 lines · 78 code · 26 blank · 22 comment · 0 complexity · 7f2025239e6c70906e0b919180606d49 MD5 · raw file

  1. /* FIXME. This is only a placeholder for the AIX compiler. */
  2. /* It doesn't work. Please send a patch. */
  3. /* Memory model documented at http://www-106.ibm.com/developerworks/ */
  4. /* eserver/articles/archguide.html and (clearer) */
  5. /* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
  6. /* There appears to be no implicit ordering between any kind of */
  7. /* independent memory references. */
  8. /* Architecture enforces some ordering based on control dependence. */
  9. /* I don't know if that could help. */
  10. /* Data-dependent loads are always ordered. */
  11. /* Based on the above references, eieio is intended for use on */
  12. /* uncached memory, which we don't support. It does not order loads */
  13. /* from cached memory. */
  14. /* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to */
  15. /* track some of this down and correcting my misunderstandings. -HB */
  16. #include "../all_aligned_atomic_load_store.h"
  17. void AO_sync(void);
  18. #pragma mc_func AO_sync { "7c0004ac" }
  19. void AO_lwsync(void);
  20. #pragma mc_func AO_lwsync { "7c2004ac" }
  21. #define AO_nop_write() AO_lwsync()
  22. #define AO_HAVE_nop_write
  23. #define AO_nop_read() AO_lwsync()
  24. #define AO_HAVE_nop_read
  25. /* We explicitly specify load_acquire and store_release, since these */
  26. /* rely on the fact that lwsync is also a LoadStore barrier. */
  27. AO_INLINE AO_t
  28. AO_load_acquire(volatile AO_t *addr)
  29. {
  30. AO_t result = *addr;
  31. AO_lwsync();
  32. return result;
  33. }
  34. #define AO_HAVE_load_acquire
  35. AO_INLINE void
  36. AO_store_release(volatile AO_t *addr, AO_t value)
  37. {
  38. AO_lwsync();
  39. *addr = value;
  40. }
  41. #define AO_HAVE_load_acquire
  42. /* This is similar to the code in the garbage collector. Deleting */
  43. /* this and having it synthesized from compare_and_swap would probably */
  44. /* only cost us a load immediate instruction. */
  45. AO_INLINE AO_TS_VAL_t
  46. AO_test_and_set(volatile AO_TS_t *addr) {
  47. # error Implement me
  48. }
  49. #define AO_have_test_and_set
  50. AO_INLINE AO_TS_VAL_t
  51. AO_test_and_set_acquire(volatile AO_TS_t *addr) {
  52. AO_TS_VAL_t result = AO_test_and_set(addr);
  53. AO_lwsync();
  54. return result;
  55. }
  56. #define AO_HAVE_test_and_set_acquire
  57. AO_INLINE AO_TS_VAL_t
  58. AO_test_and_set_release(volatile AO_TS_t *addr) {
  59. AO_lwsync();
  60. return AO_test_and_set(addr);
  61. }
  62. #define AO_HAVE_test_and_set_release
  63. AO_INLINE AO_TS_VAL_t
  64. AO_test_and_set_full(volatile AO_TS_t *addr) {
  65. AO_TS_VAL_t result;
  66. AO_lwsync();
  67. result = AO_test_and_set(addr);
  68. AO_lwsync();
  69. return result;
  70. }
  71. #define AO_HAVE_test_and_set_full
  72. AO_INLINE AO_t
  73. AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) {
  74. # error Implement me
  75. }
  76. #define AO_HAVE_compare_and_swap
  77. AO_INLINE AO_t
  78. AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {
  79. AO_t result = AO_compare_and_swap(addr, old, new_val);
  80. AO_lwsync();
  81. return result;
  82. }
  83. #define AO_HAVE_compare_and_swap_acquire
  84. AO_INLINE AO_t
  85. AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {
  86. AO_lwsync();
  87. return AO_compare_and_swap(addr, old, new_val);
  88. }
  89. #define AO_HAVE_compare_and_swap_release
  90. AO_INLINE AO_t
  91. AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
  92. AO_t result;
  93. AO_lwsync();
  94. result = AO_compare_and_swap(addr, old, new_val);
  95. AO_lwsync();
  96. return result;
  97. }
  98. #define AO_HAVE_compare_and_swap_full
  99. /* FIXME: We should also implement fetch_and_add and or primitives */
  100. /* directly. */