powerpc.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. #ifdef __NO_LWSYNC__
  20. # define AO_lwsync AO_sync
  21. #else
  22. void AO_lwsync(void);
  23. #pragma mc_func AO_lwsync { "7c2004ac" }
  24. #endif
  25. #define AO_nop_write() AO_lwsync()
  26. #define AO_HAVE_nop_write
  27. #define AO_nop_read() AO_lwsync()
  28. #define AO_HAVE_nop_read
  29. /* We explicitly specify load_acquire and store_release, since these */
  30. /* rely on the fact that lwsync is also a LoadStore barrier. */
  31. AO_INLINE AO_t
  32. AO_load_acquire(const volatile AO_t *addr)
  33. {
  34. AO_t result = *addr;
  35. AO_lwsync();
  36. return result;
  37. }
  38. #define AO_HAVE_load_acquire
  39. AO_INLINE void
  40. AO_store_release(volatile AO_t *addr, AO_t value)
  41. {
  42. AO_lwsync();
  43. *addr = value;
  44. }
  45. #define AO_HAVE_store_release
  46. #ifndef AO_PREFER_GENERALIZED
  47. /* This is similar to the code in the garbage collector. Deleting */
  48. /* this and having it synthesized from compare_and_swap would probably */
  49. /* only cost us a load immediate instruction. */
  50. /*AO_INLINE AO_TS_VAL_t
  51. AO_test_and_set(volatile AO_TS_t *addr) {
  52. # error FIXME Implement me
  53. }
  54. #define AO_HAVE_test_and_set*/
  55. AO_INLINE AO_TS_VAL_t
  56. AO_test_and_set_acquire(volatile AO_TS_t *addr) {
  57. AO_TS_VAL_t result = AO_test_and_set(addr);
  58. AO_lwsync();
  59. return result;
  60. }
  61. #define AO_HAVE_test_and_set_acquire
  62. AO_INLINE AO_TS_VAL_t
  63. AO_test_and_set_release(volatile AO_TS_t *addr) {
  64. AO_lwsync();
  65. return AO_test_and_set(addr);
  66. }
  67. #define AO_HAVE_test_and_set_release
  68. AO_INLINE AO_TS_VAL_t
  69. AO_test_and_set_full(volatile AO_TS_t *addr) {
  70. AO_TS_VAL_t result;
  71. AO_lwsync();
  72. result = AO_test_and_set(addr);
  73. AO_lwsync();
  74. return result;
  75. }
  76. #define AO_HAVE_test_and_set_full
  77. #endif /* !AO_PREFER_GENERALIZED */
  78. /*AO_INLINE AO_t
  79. AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
  80. {
  81. # error FIXME Implement me
  82. }
  83. #define AO_HAVE_fetch_compare_and_swap*/
  84. AO_INLINE AO_t
  85. AO_fetch_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val,
  86. AO_t new_val)
  87. {
  88. AO_t result = AO_fetch_compare_and_swap(addr, old_val, new_val);
  89. AO_lwsync();
  90. return result;
  91. }
  92. #define AO_HAVE_fetch_compare_and_swap_acquire
  93. AO_INLINE AO_t
  94. AO_fetch_compare_and_swap_release(volatile AO_t *addr, AO_t old_val,
  95. AO_t new_val)
  96. {
  97. AO_lwsync();
  98. return AO_fetch_compare_and_swap(addr, old_val, new_val);
  99. }
  100. #define AO_HAVE_fetch_compare_and_swap_release
  101. AO_INLINE AO_t
  102. AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
  103. AO_t new_val)
  104. {
  105. AO_t result;
  106. AO_lwsync();
  107. result = AO_fetch_compare_and_swap(addr, old_val, new_val);
  108. AO_lwsync();
  109. return result;
  110. }
  111. #define AO_HAVE_fetch_compare_and_swap_full
  112. /* TODO: Implement AO_fetch_and_add, AO_and/or/xor directly. */